feignclient对象找不到_奇葩的FeignClient问题

这些问题只是本人觉得奇葩,也许不是FeignClient的问题,whatever,只是做个记录。

1、一言不合就POST

/**

* 查询单个档案(根据档案类型名称)

* 用法:GET http://:/v1.0/devices/archives2/{archiveName}/{deviceId}

* @param deviceId 设备id

* @param archiveName 档案类型名称

* @param appToken 应用token

* @return 返回查询结果

*/

@Headers("app-token:{appToken}")

@RequestLine("GET /devices/archives2/{archiveName}/{deviceId}")

DeviceArchive findSingleArchiveByDeviceId2(@Param("appToken")String appToken,

@Param("archiveName")String archiveName,

@Param("deviceId")String deviceId);

对于上面这个接口,能看出哪里有错吗?服务端返回的报错:

Exception in thread "main" feign.FeignException: status 405 reading Mongo#findSingleArchiveByDeviceId2(String,String,String); content:

{"timestamp":1488507926013,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/devices/archives2/air_container/4661125"}

at feign.FeignException.errorStatus(FeignException.java:62)

at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:91)

at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:134)

at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)

at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)

at com.sun.proxy.$Proxy4.findSingleArchiveByDeviceId2(Unknown Source)

at com.chinamobile.iot.App.main(App.java:18)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:497)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

第一反应是见了鬼了,明明是GET,怎么会提示"Request method 'POST' not supported"。搞了半天才发现是@Herders里边的键值对冒号后面必须有个空格!正确的写法:

@Headers("app-token: {appToken}")

另外,如果GET方法有一堆参数:

/**

* 查询单个设备数据

* 用法:GET http://:/v1.0/devices/datas/{deviceId}

* @param deviceId 设备ID

* @param appToken 应用Token

* @param deviceDataId 数据集合的UUID

* @param deviceDataName 数据名

* @param filters 过滤条件

* @param limit 最大查询数据量

* @param startTime 开始时间

* @param endTime 结束时间

* @return 返回查询结果

*/

想要设置一个request实体类,把所有参数都包进去,放到HTTP 的body来上传,也会被当成POST。一句话:GET参数不支持复杂对象(只支持String、Integer这些简单对象)

2、传的是NULL,收到的是参数名

例子如下:

@RequestLine("POST /mongodb/datas")

boolean addBatchDatas(@Param("app-token") String appToken, AddBatchDataRequest addBatchDataRequest);

如果传参的时候,因为某些原因给appToken传的是null(并非有意要传null,有时是程序出现了bug)

mongo.addBatchDatas(null, addBatchDataRequest); //mongo是已初始化的Feign对象

服务端报错,输出的调试信息如下:

appToken={app-token}

当第一次遇到这个问题的时候,百思不得其解为何appToken会被设为“{app-token}”,调试了半天才发现是设值null时Feign就会传这个,私以为Feign更合理的做法是提示某某参数为null。

3、服务是POST,Client错写为GET

服务端是POST:

@RequestMapping(value = "{productId}", method = RequestMethod.GET)

ProductInfo getProduct(@PathVariable("productId") Integer productId);

@RequestMapping(value = "getByProductKey", method = RequestMethod.POST)

public ProductInfo getByProductKey(@RequestParam("productKey") String productKey);

Client错把getByProductKey写为GET

@RequestMapping(value = "{productId}", method = RequestMethod.GET)

ProductInfo getProduct(@PathVariable("productId") Integer productId);

@RequestMapping(value = "getByProductKey", method = RequestMethod.GET)

ProductInfo getByProductKey(@RequestParam("productKey") String productKey);

客户端调用时报错:

"message":"Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: \"getByProductKey\""

服务端打印的调试信息也很奇怪,明明调的是getByProductKey,怎么变成了getProduct:

GET 192.168.1.115:9000/products/getByProductKey?productKey=ukyUPF7S started, method=getProduct

4、直接返回NULL

如果忘了加@EnableFeignClients,则会直接调callback,导致返回null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值