You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@FeignClient调用微服务时出现Method Not Allowed错误求助

问题:FeignClient跨服务调用出现Method Not Allowed错误

项目包含三个微服务:Hotel Service、Hotel-rating Service、User-service。通过User-Service调用Hotel-Service时触发错误:"Method Not Allowed while using @FeignClient",依赖为Spring Cloud Eureka client/server、FeignClient。


User Controller代码

@GetMapping("/{userId}")
public ResponseEntity<?> getUser(@PathVariable("userId") String userId) {
    User user = this.userService.getUser(userId);
    return new ResponseEntity<>(user, HttpStatus.OK);
}

UserServiceImpl代码

@Override
public User getUser(String userId) {
    User user = this.userRepo.findById(userId).orElseThrow(() -> new ResourceNotFounds("user id not found " + userId));

    ResponseEntity<List<Rating>> ratingByUser = this.hotelRating.getRatingByUser(user.getId());// 使用FeignClient
    List<Rating> ratings = ratingByUser.getBody();
    user.setRatings(ratings);

    // 从Hotel服务获取酒店信息
    List<Rating> collect = ratings.stream().map(userH -> {
        logger.info("Hotel Id "+ userH.getHotelId());
        ResponseEntity<Hotel> hotelResponse = hotelService.getHotel(userH.getHotelId());
        logger.info("status code ", hotelResponse.getStatusCode());

        Hotel hotel = hotelResponse.getBody();

        // 为User对象设置Hotel对象
        userH.setHotel(hotel);
        return userH;
    }).collect(Collectors.toList());

    return user;
}

HotelService(UserService中FeignClient接口)

@Service
@FeignClient(name = "HOTEL-SERVICE")
public interface HotelService {

    // @GetMapping("/hotel/{hotelId}")
    // Hotel getHotel(@PathVariable("hotelId") String hotelId);

    @RequestMapping(method = RequestMethod.GET, value = "/hotel/{hotelId}")
    ResponseEntity<Hotel> getHotel(@PathVariable("hotelId") String hotelId);

    // 获取所有酒店信息
    @GetMapping("/hotel/all")
    ResponseEntity<List<Hotel>> getAllHotelList();
}

HotelController(被调用的Hotel服务接口)

@GetMapping("/{hotelId}")
public ResponseEntity<Hotel> getHotel(@PathVariable("hotelId") String hotelId){
    Hotel hotel = this.hotelService.getHotel(hotelId);
    return new ResponseEntity<>(hotel , HttpStatus.OK);
}

错误信息

feign.FeignException$MethodNotAllowed: [405] during [GET] to [http://HOTEL-SERVICE/hotel/] [HotelService#getHotel(String)]: [{"timestamp":"2023-02-26T16:21:16.604+00:00","status":405,"error":"Method Not Allowed","path":"/hotel/"}]
    at feign.FeignException.clientErrorStatus(FeignException.java:221) ~[feign-core-11.10.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-11.10.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:185) ~[feign-core-11.10.jar:na]

测试环境正常情况

@Autowired
private HotelService hotelService;

@Test
void getSingleHotelInfor(){
    ResponseEntity<Hotel> hotel = this.hotelService.getHotel("72db342b-678c-486b-8d37-25b97851cec6");
    System.out.println(hotel.getBody().getName());
}

解决方案

1. 对齐HotelController的请求前缀

从错误信息可见,Feign实际请求路径为/hotel/(未携带hotelId),核心问题是Feign接口定义的路径与Hotel服务实际接口路径不匹配:

  • Feign接口中定义的路径是/hotel/{hotelId}
  • 当前HotelController的方法仅配置了@GetMapping("/{hotelId}"),若Controller类无@RequestMapping("/hotel")前缀,实际接口路径应为/{hotelId},与Feign定义的路径不符。

修复方式:给HotelController类添加路径前缀,确保路径匹配:

@RequestMapping("/hotel")
@RestController
public class HotelController {
    @GetMapping("/{hotelId}")
    public ResponseEntity<Hotel> getHotel(@PathVariable("hotelId") String hotelId){
        Hotel hotel = this.hotelService.getHotel(hotelId);
        return new ResponseEntity<>(hotel , HttpStatus.OK);
    }
}

2. 过滤无效的hotelId数据

测试环境正常但业务调用出错,大概率是从Hotel-rating Service获取的ratings列表中存在空/空白的hotelId:
当userH.getHotelId()为空时,Feign会生成/hotel/的请求路径,而Hotel服务未定义该路径的GET接口,导致405错误。

修复方式:在代码中添加空值过滤逻辑:

// 过滤掉hotelId为空的rating数据
List<Rating> collect = ratings.stream()
    .filter(rating -> rating.getHotelId() != null && !rating.getHotelId().trim().isEmpty())
    .map(userH -> {
        logger.info("Hotel Id "+ userH.getHotelId());
        ResponseEntity<Hotel> hotelResponse = hotelService.getHotel(userH.getHotelId());
        logger.info("status code ", hotelResponse.getStatusCode());

        Hotel hotel = hotelResponse.getBody();
        userH.setHotel(hotel);
        return userH;
    }).collect(Collectors.toList());

3. 简化FeignClient接口定义

将Feign接口中的@RequestMapping替换为更简洁的@GetMapping,避免配置冗余:

@FeignClient(name = "HOTEL-SERVICE")
public interface HotelService {
    @GetMapping("/hotel/{hotelId}")
    ResponseEntity<Hotel> getHotel(@PathVariable("hotelId") String hotelId);

    @GetMapping("/hotel/all")
    ResponseEntity<List<Hotel>> getAllHotelList();
}

内容的提问来源于stack exchange,提问作者Jitendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:47:06