Spring Feign GetMapping传Criteria参数遇405错误的问题排查
问题描述
我尝试从Organisation微服务获取UserConfig,随着应用规模扩大,需要通过UserConfigFeignCriteria筛选UserConfig。编写Feign服务、调用实现代码后,调用时抛出405错误,且Organisation微服务的目标端点未被触发,需排查原因并实现UserConfigFeignCriteria的正常传递。
Feign服务代码
@AuthorizedFeignClient(name = "organization") @Service public interface UserConfigFeignService { @RequestMapping( value = "/api/feign-user-configs", consumes = "application/json", produces = "application/json", method = RequestMethod.GET ) ResponseEntity<List<UserConfigFein>> getUserConfig(UserConfigFeignCriteria criteria); }
调用实现代码
public List<UserConfigFein> UserConfigByDepartment(UserConfigFeignCriteria criteria) { try { return userConfigFeignService.getUserConfig(criteria).getBody(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("feign error: couldn't get all userConfigs with criteria " + criteria); } }
Organisation微服务端点代码
@GetMapping("/feign-user-configs") public ResponseEntity<List<UserConfigDTO>> getUserConfig(UserConfigCriteria criteria) { log.debug("REST request to get a page of UserConfigs by criteria: {}", criteria); //未执行到此处代码 }
错误信息
调用时在throw new RuntimeException("feign error: couldn't get all userConfigs with criteria " + criteria);处抛出以下错误:
[405 Method Not Allowed] during [GET] to [http://organization/api/feign-user-configs] [UserConfigFeignService#getUserConfigByDepartmentId(UserConfigFeignCriteria)]: [{ "title" : "Method Not Allowed", "status" : 405, "detail" : "Request method 'POST' not supported", "path" : "/api/feign-user-configs", "message" : "error.http.405" }]
补充:UserConfigFeignCriteria代码
@ParameterObject public class UserConfigFeignCriteria implements Serializable, Criteria { private LongFilter id; private StringFilter userId; private StringFilter nickname; private Boolean focusMode; private LongFilter departmentId; private Boolean distinct; public UserConfigFeignCriteria(UserConfigFeignCriteria other) { this.id = other.id == null ? null : other.id.copy(); this.userId = other.userId == null ? null : other.userId.copy(); this.nickname = other.nickname == null ? null : other.nickname.copy(); this.focusMode = other.focusMode; this.distinct = other.distinct; } public UserConfigFeignCriteria() {} @Override public UserConfigFeignCriteria copy() { return new UserConfigFeignCriteria(this); } //getters and setters @Override public boolean equals(Object o) @Override public int hashCode() @Override public String toString() }
原因分析
- Feign GET请求的参数处理逻辑:Feign默认会将GET方法中的对象参数放入请求体发送,导致实际请求变为POST,但目标端点仅支持GET,因此返回405方法不允许错误。
- 缺少参数绑定注解:Feign接口中的
UserConfigFeignCriteria参数未添加注解,无法被解析为URL查询参数,只能退化为POST请求传递请求体。
解决方案
方案一:使用@SpringQueryMap注解(推荐)
修改Feign接口方法,添加@SpringQueryMap注解,让Feign将对象属性解析为URL查询参数传递:
@AuthorizedFeignClient(name = "organization") @Service public interface UserConfigFeignService { @RequestMapping( value = "/api/feign-user-configs", produces = "application/json", method = RequestMethod.GET ) ResponseEntity<List<UserConfigFein>> getUserConfig(@SpringQueryMap UserConfigFeignCriteria criteria); }
提示:可以移除
consumes = "application/json",因为GET请求不存在请求体。
方案二:拆分对象为多个@RequestParam参数
若UserConfigFeignCriteria属性较少,可直接将每个属性作为单独的@RequestParam参数传递:
@AuthorizedFeignClient(name = "organization") @Service public interface UserConfigFeignService { @RequestMapping( value = "/api/feign-user-configs", produces = "application/json", method = RequestMethod.GET ) ResponseEntity<List<UserConfigFein>> getUserConfig( @RequestParam(required = false) LongFilter id, @RequestParam(required = false) StringFilter userId, // 依次添加其他属性参数 @RequestParam(required = false) Boolean distinct ); }
此方式在属性较多时会显得繁琐,不如方案一简洁。
端点参数接收验证
Organisation微服务的端点已添加@ParameterObject注解,Spring Boot会自动将URL查询参数绑定到UserConfigCriteria对象属性,无需额外修改,只要Feign正确传递参数即可触发端点逻辑。
内容的提问来源于stack exchange,提问作者Fendri
相关产品推荐
相关产品推荐

