前言:一般来说,不建议在文件上传时使用openfeign接口调用,因为容易导致feign接口超时,接口超时就需要对特点接口设置不同的超时时间。总之麻烦容错率高低。
话不多说,直奔主题------------------->
openfeign文件上传
1. 单文件上传
- 单文件上传使用 @RequestParam + @RequestPart 就能轻松搞定。
- feign接口层和提供者服务的接口写法相同。
@PostMapping(value="/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public CommonResult<String> upload(@RequestParam("tag") String tag, @RequestPart("file") MultipartFile file){
//文件上传处理
return providerService.upload(tag, file);
}
2. 多文件上传
2.1 多文件上传携带单参数
- 多文件上传时,只需改用 MultipartFile[] 接收即可。
@PostMapping(value="/upload/batch", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public CommonResult<String> uploadBatch(@RequestParam("tag") String tag,
@RequestPart("files") MultipartFile[] files){
return providerService.uploadBatch(tag, files);
}
2.2 多文件上传携带复杂参数
- 当我们需要在文件上传同时携带多个参数,需要使用对象去接收时。
- 使用 @requestBody 或者不加注解都是不行的。不加注解时,A -> B,B服务拿不到实体类中传的参数。
- 有说用 Map去接收的,但是实现挺麻烦。
- 这里给出一个简单的方式:使用 @ModelAttribute 注解,把参数封装到一个对象中。
调用方:
@PostMapping(value="/upload/batch/V3", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public CommonResult<String> uploadBatchV3(@ModelAttribute UploadFileParamV3 tag){
return providerService.uploadBatchV3(tag);
}
接口层:
@PostMapping(value = "/provider/upload/batch/V3", consumes = MediaType.MULTIPAR T_FORM_DATA_VALUE)
CommonResult<String> uploadBatchV3(@ModelAttribute UploadFileParamV3 tag);
执行方:
@PostMapping(value="/upload/batch/V3", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)public
CommonResult<String> uploadBatchV3(@ModelAttribute UploadFileParamV3 tag){
// 省略...
}
参数接收实体类:
@Data
@EqualsAndHashCode
public class UploadFileParamV3 {
private MultipartFile[] files;
private String username;
private String password;
}
3. 注意事项:
- 配置文件上传的大小限制
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 15MB
- feign 配置
@Configuration
@RequiredArgsConstructor
public class FeignConfiguration implements RequestInterceptor {
final ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Retryer feignRetryer() {
// 使用默认的重试策略,最大重试次数为5,初始间隔为100毫秒,最大间隔为1秒,间隔乘数为2
return new Retryer.Default();
}
@Bean
@Primary
@Scope("prototype")
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
if ("content-type".equals(name) || "content-length".equals(name)) {
continue;
}
requestTemplate.header(name, values);
}
}
}
}
}