上传文件往往会独立成一个单独的微服务,作为一个通用的服务,以实现与其他服务的解耦,其他服务需要上传文件就需要通过Feign的方式调用文件管理服务的上传文件接口,然而如果直接调用Feign的接口上传文件,接口会报错,参数为空,因此需要通过DiskFileItem指定feign接口的文件参数名称。
注意createItem方法的第一个参数是你服务接收的参数名称,这个如果与服务接收不一致接口接收不到文件,第二个参数是你组装的类型,由于指定了consumes,这里写什么都可以,第三个参数是否是模拟表单,true/false均可,第四个参数是文件名称了。
//image为feign接口的文件参数名
private MultipartFile formatMultipartFile(MultipartFile multipartFile) {
String fileName = multipartFile.getName();
FileItemFactory factory = new DiskFileItemFactory();
DiskFileItem item = (DiskFileItem) factory.createItem("image", MediaType.APPLICATION_OCTET_STREAM_VALUE, true, multipartFile.getName());
try (InputStream in = multipartFile.getInputStream(); OutputStream out = item.getOutputStream()) {
IOUtils.copy(in, out);
MultipartFile uploadFile = new CommonsMultipartFile(item);
return uploadFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Feign接口参数注解用@RequestPart,指定formdata请求方式MediaType.MULTIPART_FORM_DATA_VALUE
@FeignClient(name = "VI-OSS-SERVICE" ,fallbackFactory = OssServiceFallbackFactory.class,configuration = FeignClientConfig.class)
public interface OssClientService {
@PostMapping(value = "/images/upload/single", consumes =MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
JSONObject uploadImage(@RequestPart("image") MultipartFile file);
}
文件管理服务接口
@ApiOperation(value = "图片", notes = "单张图片上传,单张图片大小限制为1M")
@ApiImplicitParams({
@ApiImplicitParam(name = "returnUrl", value = "是否返回完整可访问URL", paramType = "query")
})
@PostMapping("upload/single")
public Result<FileStoreInfo> upload(@RequestParam("image") MultipartFile image,
@RequestParam(required = false, defaultValue = "false") boolean returnUrl) {
if(Objects.nonNull(image)){
FileMetadata fileMetadata = FileUtils.extractFileMetadata(image);
return ResultUtils.success(fileOperationService.storeImage(fileMetadata, returnUrl));
}
return ResultUtils.error("Not found image");
}