在使用feign时,遇到这么一个问题,代码如下
@PostMapping(value = "/funds_transfer/charge_strategy/apply", consumes = "application/x-www-form-urlencoded;charset=GB18030")
String chargeStrategyApply(@RequestBody Map<String,String> param);
我使用的是POST提交content-type是form表单application/x-www-form-urlencoded,字符集是gb18080(为适配百度系的祖传系统额。。。),入参我想传Map(实际我传的是HashMap),测试时发现报异常
Could not write request: no suitable HttpMessageConverter found for request type [java.util.HashMap] and content type [application/x-www-form-urlencoded;charset=GB18030]
feign.codec.EncodeException: Could not write request: no suitable HttpMessageConverter found for request type [java.util.HashMap] and content type [application/x-www-form-urlencoded;charset=GB18030]
at org.springframework.cloud.openfeign.support.SpringEncoder.encode(SpringEncoder.java:143) ~[spring-cloud-openfeign-core-2.2.2.RELEASE.jar!/:2.2.2.RELEASE]
at org.springframework.cloud.openfeign.support.PageableSpringEncoder.encode(PageableSpringEncoder.java:101) ~[spring-cloud-openfeign-core-2.2.2.RELEASE.jar!/:2.2.2.RELEASE]
at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:380) ~[feign-core-10.7.4.jar!/:?]
at feign.ReflectiveFeign$BuildTemplateByResolvingArgs.create(ReflectiveFeign.java:232) ~[feign-core-10.7.4.jar!/:?]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:75) ~[feign-core-10.7.4.jar!/:?]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100) ~[feign-core-10.7.4.jar!/:?]
at com.sun.proxy.$Proxy176.chargeStrategyApply(Unknown Source) ~[?:?]
为什么简单的map都不支持呢?feign使用的是springMVC的HttpMessageConverter做请求和响应体转化,我跟了一下代码,发现在判断使用哪个Converter时,不支持HashMap。我第一时间想到不是要自定义HttpMessageConverter吧,这就有点麻烦了,我找了下本来预期要使用的转换from表单的Converter,发现MultiValueMap字样,突然想到springMVC controller返回页面时数据可以放在MultiValueMap里,这个spring自定义的数据结构应该可以用,我改了下代码,如下
@PostMapping(value = "/funds_transfer/charge_strategy/apply", consumes = "application/x-www-form-urlencoded;charset=GB18030")
String chargeStrategyApply(@RequestBody MultiValueMap<String,String> param);
MultiValueMap是一个接口可以看下源码,我用的是LinkedMultiValueMap实现类,果然没有问题了。 那么为什么要用这个MultiValueMap呢?因为HTTP表单格式中key是可以允许重复的,a=1&a=2,代表a是一个list,MultiValueMap的value其实就是一个list,这样满足表单数据结构了。 深刻领悟到用好SpringMVC,必须先搞懂HttpMessageConverter。