zuul feign微服務間文件上傳
阿新 • • 發佈:2018-08-31
通過 let net 上傳 int @override note into ati
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>
- 增加配置類
@Configuration public 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 Servlet
Zuul is implemented as a Servlet. For the general cases, Zuul is embedded
into the Spring Dispatch mechanism. This allows Spring MVC to be in control
of the routing. In this case, Zuul is configured to buffer requests. If
there is a need to go through Zuul without buffering requests (e.g. for
large file uploads), the Servlet is also installed outside of the Spring
Dispatcher. By default, this is located at /zuul. This path can be changed
with the zuul.servlet-path property.
zuul feign微服務間文件上傳