1.添加配置类
@Configuration
public class FeignSupportConfig {
@Bean
public Encoder feignFormEncoder() {
return new FeignSpringFormEncoder();
}
}
2.重写SpringFormEncoder
发现网上很多博文都是重写FormEncoder类,试了下没有效果,而且会引发其他的问题.
研究下了源码,发现了SpringFormEncoder类可以使用.
/**
* 扩展FormEncoder支持多文件上传
*/
public class FeignSpringFormEncoder extends SpringFormEncoder {
/**
* Constructor with the default Feign's encoder as a delegate.
*/
public FeignSpringFormEncoder() {
this(new Encoder.Default());
}
/**
* Constructor with specified delegate encoder.
*
* @param delegate delegate encoder, if this encoder couldn't encode object.
*/
public FeignSpringFormEncoder(Encoder delegate) {
super(delegate);
MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(ContentType.MULTIPART);
processor.addWriter(new SpringSingleMultipartFileWriter());
processor.addWriter(new SpringManyMultipartFilesWriter());
}
@Override
public void encode (Object object, Type bodyType, RequestTemplate template) throws EncodeException {
if (bodyType.equals(MultipartFile[].class)) {
// 主要是改造这里
val files = (MultipartFile[]) object;
if(files != null) {
val data = Collections.singletonMap(files.length == 0 ? "" : files[0].getName(), object);
super.encode(data, MAP_STRING_WILDCARD, template);
}
} else if (bodyType.equals(MultipartFile.class)) {
val file = (MultipartFile) object;
val data = singletonMap(file.getName(), object);
super.encode(data, MAP_STRING_WILDCARD, template);
} else if (isMultipartFileCollection(object)) {
val iterable = (Iterable<?>) object;
val data = new HashMap<String, Object>();
for (val item : iterable) {
val file = (MultipartFile) item;
data.put(file.getName(), file);
}
super.encode(data, MAP_STRING_WILDCARD, template);
} else {
super.encode(object, bodyType, template);
}
}
private boolean isMultipartFileCollection (Object object) {
if (!(object instanceof Iterable)) {
return false;
}
val iterable = (Iterable<?>) object;
val iterator = iterable.iterator();
return iterator.hasNext() && iterator.next() instanceof MultipartFile;
}
}
3.文件上传接口
/**
* 文件操作Feign接口
*/
@FeignClient(
value = "file-service",
path = "/file",
fallback = FileOperationClientFallback.class,
configuration = FeignSupportConfig.class)
public interface IFileOperationClient {
/**
* 上传文件
*
* @param file 文件
* @return 文件存储URL
*/
@PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String uploadFile(@RequestPart("file") MultipartFile file);
/**
* 批量上传文件
*
* @param files 文件数组
* @return 文件存储URL数组
*/
@PostMapping(value = "/uploadFiles", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
Map<String, List<String>> uploadFiles(@RequestPart("files") MultipartFile[] files);
}