feign传文件
- 需求
- 文件微服务负责管理文件,具体的文件上传下载逻辑都在此模块。
- openAPI负责向app用户提供头像上传的接口,实现具体业务逻辑。
- zuul是网关,负责路由转发。用户直接访问网关。
头像文件==》zuul==》openAPI==》文件微服务
- 增加引用包
???????<dependency> ???????????<groupId>io.github.openfeign.form</groupId> ???????????<artifactId>feign-form</artifactId> ???????????<version>2.1.0</version> ???????</dependency> ???????<dependency> ???????????<groupId>io.github.openfeign.form</groupId> ???????????<artifactId>feign-form-spring</artifactId> ???????????<version>2.1.0</version> ???????</dependency>
- 增加配置类
@Configurationpublic class FeignConfiguration { ???@Autowired ???private ObjectFactory<HttpMessageConverters> messageConverters; ???@Bean ???public Retryer retryer(){ ???????return new Retryer.Default(1000,10000,3); ???} ???@Bean ???Request.Options feignOptions() { ???????return new Request.Options(5 * 1000, 10 * 1000); ???} ???// 主要是这个地方 ???@Bean ???@Primary ???@Scope("prototype") ???public Encoder multipartFormEncoder() { ???????return new SpringFormEncoder(new SpringEncoder(messageConverters)); ???} ???@Bean ???public Logger.Level feignLoggerLevel() { ???????return Logger.Level.FULL; ???} ???@Bean ???public ErrorDecoder errorDecoder(){ ???????return new FeignErrorDecoder(); ???}}
异常处理类
public class FeignErrorDecoder implements feign.codec.ErrorDecoder { ???private static final Logger logger = LoggerFactory.getLogger(FeignErrorDecoder.class); ???@Override ???public Exception decode(String methodKey, Response response) { ???????if(response.status() >= 400 && response.status() <= 499){ ???????????return new HystrixBadRequestException("微服务之间调用失败!"); ???????} ???????return feign.FeignException.errorStatus(methodKey, response); ???}}
在启动类上加注解@Import(FeignConfiguration.class),导入配置类
@Import(FeignConfiguration.class)
至此可实现feign中文件传递
feignclient
@ApiOperation(value = "用户修改头像", notes = "用户修改头像") @RequestMapping(value = "/v1/user/avatar", method = RequestMethod.PUT) public CommonResponse editAvatar(@RequestHeader(value = "openId") String openId, ????????????????????????????????????@RequestPart(value = "file") MultipartFile avatarFile);
- RequestPart中的name要和上传时一致,否则调用失败。
- feign中@RequestHeader传递null时,会自动转为{fileLength},需要手动处理。
zuul
微服务上传文件成功后,通过zuul网关上传又出现问题,文件传不到微服务中。
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part ‘file‘ is not present
解决方法:
在调用地址前加上/zuul(/zuul/v1/user/avatar),绕过spring mvc,使用zuul servlet去上传文件。
参考:https://my.oschina.net/kmnztech/blog/1618636
或者在网关的application.properties中设置servlet-path属性
zuul.servlet-path=/
官方文档:
http://cloud.spring.io/spring-cloud-static/Dalston.SR1/#_uploading_files_through_zuul
The Zuul ServletZuul is implemented as a Servlet. For the general cases, Zuul is embeddedinto the Spring Dispatch mechanism. This allows Spring MVC to be in controlof the routing. In this case, Zuul is configured to buffer requests. Ifthere is a need to go through Zuul without buffering requests (e.g. forlarge file uploads), the Servlet is also installed outside of the SpringDispatcher. By default, this is located at /zuul. This path can be changedwith the zuul.servlet-path property.
zuul feign微服务间文件上传
原文地址:https://www.cnblogs.com/iiot/p/9567255.html