spring cloud feign 上传文件报not a type supported by this encoder解决方案
上传文件调用外部服务报错: not a type supported by this encoder
查看SpringFormEncoder类的源码:
1 public class SpringFormEncoder extends FormEncoder 2 { 3 4 public SpringFormEncoder() 5 { 6 this(((Encoder) (new feign.codec.Encoder.Default()))); 7 } 8 9 public SpringFormEncoder(Encoder delegate) 10 { 11 super(delegate);//调用父类的构造方法 12 MultipartFormContentProcessor processor = (MultipartFormContentProcessor)getContentProcessor(ContentType.MULTIPART); 13 processor.addWriter(new SpringSingleMultipartFileWriter()); 14 processor.addWriter(new SpringManyMultipartFilesWriter()); 15 } 16 17 public void encode(Object object, Type bodyType, RequestTemplate template) 18 throws EncodeException 19 { 20 if(!bodyType.equals(org/springframework/web/multipart/MultipartFile)) 21 { 22 super.encode(object, bodyType, template);//调用FormEncoder对应方法 23 return; 24 } else 25 { 26 MultipartFile file = (MultipartFile)object; 27 java.util.Map data = Collections.singletonMap(file.getName(), object); 28 super.encode(data, MAP_STRING_WILDCARD, template); 29 return; 30 } 31 } 32 }
可以发现SpringFormEncoder的encode方法当传送的对象不是MultipartFile的时候,就会调用super.encode, 也就是FormEncoder的encode方法。
FormEncoder类的部分源码:
1 public FormEncoder() 2 { 3 this(((Encoder) (new feign.codec.Encoder.Default()))); 4 } 5 6 public FormEncoder(Encoder delegate) 7 { 8 _flddelegate = delegate; 9 List list = Arrays.asList(new ContentProcessor[] { 10 new MultipartFormContentProcessor(delegate), new UrlencodedFormContentProcessor() 11 }); 12 processors = new HashMap(list.size(), 1.0F); 13 ContentProcessor processor; 14 for(Iterator iterator = list.iterator(); iterator.hasNext(); processors.put(processor.getSupportedContentType(), processor)) 15 processor = (ContentProcessor)iterator.next(); 16 17 } 18 19 public void encode(Object object, Type bodyType, RequestTemplate template) 20 throws EncodeException 21 { 22 String contentTypeValue = getContentTypeValue(template.headers());//这里会去到@PostMapping中consumes的值,所以参数需要传对象时指定一下consumes 23 ContentType contentType = ContentType.of(contentTypeValue);//为啥指定consumes,是因为不指定就是application/x-www-form-urlencoded,而且processors中也包含,为啥包含见FormEncoder的构造函数 24 if(!MAP_STRING_WILDCARD.equals(bodyType) || !processors.containsKey(contentType)) 25 { 26 _flddelegate.encode(object, bodyType, template);//_flddelegate是啥呢,是SpringFormEncoder传递过来,也就是new Encoder.Default() 27 return; 28 } 29 Charset charset = getCharset(contentTypeValue); 30 Map data = (Map)object; 31 try 32 { 33 ((ContentProcessor)processors.get(contentType)).process(template, charset, data); 34 } 35 catch(Exception ex) 36 { 37 throw new EncodeException(ex.getMessage()); 38 } 39 }
FormEncoderr的encode方法当传送的对象是json格式的字符串的时候,就会调用 _flddelegate.encode,即Encoder.Default的encode方法,而这个Encoder.Default的encode方法判断传送的类型不是String或者byte[],就会抛异常
1 public interface Encoder 2 { 3 public static class Default 4 implements Encoder 5 { 6 7 public void encode(Object object, Type bodyType, RequestTemplate template) 8 { 9 if(bodyType == java/lang/String) 10 template.body(object.toString()); 11 else 12 if(bodyType == [B) 13 template.body((byte[])(byte[])object, null); 14 else 15 if(object != null)//当我们用对象传递参数的时候,会走这里 16 throw new EncodeException(String.format("%s is not a type supported by this encoder.", new Object[] { 17 object.getClass() 18 })); 19 } 20 21 public Default() 22 { 23 } 24 } 25 26 27 public abstract void encode(Object obj, Type type, RequestTemplate requesttemplate) 28 throws EncodeException; 29 30 public static final Type MAP_STRING_WILDCARD = Util.MAP_STRING_WILDCARD; 31 32 }
解决方案一:继续使用前面提到的方案,如果引用该配置类的FeignClient中,没有使用实体类作为参数的接口,则去掉配置类上的注解@Configuration就可以了,去掉注解@Configuration之后,该配置就只对通过configuration属性引用该配置的FeignClient起作用(或者将该文件上传接口单独放到一个FeignClient中,去掉配置类上的注解@Configuration)。
方案一只支持文件上传,如果引用该配置的FeignClient中有使用实体类作为参数接收的接口,则调用该接口时会抛异常。
解决方案二:继续使用前面提到的方案,将配置文件修改为如下:
1 @Configuration 2 class MultipartSupportConfig { 3 @Autowired 4 private ObjectFactory<HttpMessageConverters> messageConverters; 5 6 @Bean 7 public Encoder feignFormEncoder() { 8 return new SpringFormEncoder(new SpringEncoder(messageConverters)); 9 } 10 }
方案二既支持文件上传也支持实体类作为参数接收。
转载于:https://www.cnblogs.com/UniqueColor/p/9647776.html
spring cloud feign 上传文件报not a type supported by this encoder解决方案相关推荐
- Spring MVC实现上传文件报错解决方案
Spring MVC实现上传文件报错解决方案 参考文章: (1)Spring MVC实现上传文件报错解决方案 (2)https://www.cnblogs.com/liuling/p/2014-3-5 ...
- ftp上传文件报错“200 Type set tol.200 PORT command scesful.4MUM np for he Uicde hater eit inte onetmult”
上传文件名是中文导致的 解决办法 文件名使用英文字符
- Spring Boot上传文件报UT005023 MultipartException NoSuchFileException
1.抛出问题: Spring Boot上传文件报: UT005023: Exception handling request to /management/certificateAuthority/u ...
- springcloud上传文件报错
Spring Cloud上传文件报如下错误: The temporary upload location [/tmp/tomcat.5260880110861696164.8090/work/Tomc ...
- ajax上传文件报错The current request is not a multipart request的解决办法
ajax上传文件报错The current request is not a multipart request的解决办法 主要报错语句为: The current request is not a ...
- laravel上传文件报错:413 Request Entity Too Large
上传图片的时候,是用laravel自带的上传图片的方法,一下气上传了20张,结果就无情报错: 413 Request Entity Too Large,后面查一下,这个报错信息是nginx报的错误,不 ...
- spring mvc(注解)上传文件的简单例子
spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方 1.form的enctype="multipart/form-data" 这个是上传文件必须的 2.appl ...
- php图片上传报502,PHPStrom上传文件报502错误原因,_PHP教程
PHPStrom上传文件报502错误原因, PhpStorm是一个轻量级且便捷的PHP IDE,其自身拥有apache类似的编译器,能够在无Apache的情况下运行,很适合初学PHPStrom的朋友. ...
- Linux - xshell上传文件报错乱码
xshell上传文件报错乱码,解决方法 rz -be 回车 下载sz filename 转载于:https://www.cnblogs.com/RzCong/p/8600899.html
最新文章
- ubuntu 系统下安装 xlwt
- linux系统下的动态壁纸,您可以在下面下载动态壁纸APK和linuxct的配套应用
- 数学系鄙视物理系的经典桥段,全部看懂了算我输!
- c++怎么将两个类的方法集合成一个类的方法_一文帮你梳理 Java 集合
- ioctl(), ioctl_socket()
- 电脑显示器不亮主机正常_电脑显示屏不亮但是主机已开机怎么解决
- SparkSQL概念介绍
- mysql 之根据日期(时间)过滤数据
- java线程从没入门就放弃
- mysql一般要配置的几个小节及选项是_MySQL - 必知必会(下)
- websocket 应用实例
- linux的vi编辑器的dd命令,linux vi 后dd命令
- matlab开环传递函数 求单位负反馈的系统传递函数,已知负反馈控制系统的开环传递函数为...
- 微信公众号网页登录开发测试步骤详解
- 计算机组成x什么意思,cpu后面带x是什么意思
- JWT令牌生成与校验
- “辉夜姬”:多利之后的动物明星
- 网站反爬指南:政府网站篇
- 磁盘最优存储问题---Python
- linux能修改用户的权限,linux怎样修改用户权限