這期內容當中小編將會給大家帶來有關怎么在Spring Cloud中使用FeignClient實現文件上傳功能,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
具體的使用方法是加入maven依賴
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.2.2</version> </dependency>
注入SpringFormEncoder類
@Bean
@Primary
@Scope("prototype")
public Encoder multipartFormEncoder() {
return new SpringFormEncoder();
}FeignClient接口里方法參數是文件類型的要用@RequestPart注解,且要設置ContentType為multipart/form-data
@ResponseBody
@RequestMapping(value = "/ctstestcase/updateTestCase", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
Map<String, Object> updateTestCase(@RequestParam("testcaseId") String testcaseId,
@RequestParam("name") String name, @RequestParam("assignId") String assignId,
@RequestParam("areaId") String areaId, @RequestParam("state") Integer state,
@RequestParam("iterationId") String iterationId,@RequestParam("priority") Integer priority,
@RequestParam("moduleId") String moduleId, @RequestParam("executionType") Integer executionType,
@RequestParam("summary") String summary, @RequestParam("tcsteps") String tcsteps,
@RequestParam("relations") String relations,@RequestParam("attachments") String attachments,
@RequestPart("files") MultipartFile[] files);但遇到一個問題,就是不支持文件數組類型,我看了源碼,發現源碼里底層是有對MultipartFile[]類型的支持的,源碼中有個類叫SpringManyMultipartFilesWriter,是專門針對文件數組類型進行操作的,但是配置到項目里的SpringFormEncoder類里卻沒有對文件數組類型的判斷,以致不能支持文件數組的上傳.。
SpringManyMultipartFilesWriter源碼:
@FieldDefaults(level = PRIVATE, makeFinal = true)
public class SpringManyMultipartFilesWriter extends AbstractWriter {
SpringSingleMultipartFileWriter fileWriter = new SpringSingleMultipartFileWriter();
@Override
public void write (Output output, String boundary, String key, Object value) throws Exception {
if (value instanceof MultipartFile[]) {
val files = (MultipartFile[]) value;
for (val file : files) {
fileWriter.write(output, boundary, key, file);
}
} else if (value instanceof Iterable) {
val iterable = (Iterable<?>) value;
for (val file : iterable) {
fileWriter.write(output, boundary, key, file);
}
}
}
@Override
public boolean isApplicable (Object value) {
if (value == null) {
return false;
}
if (value instanceof MultipartFile[]) {
return true;
}
if (value instanceof Iterable) {
val iterable = (Iterable<?>) value;
val iterator = iterable.iterator();
if (iterator.hasNext() && iterator.next() instanceof MultipartFile) {
return true;
}
}
return false;
}SpringFormEncoder源碼:
public class SpringFormEncoder extends FormEncoder {
/**
* Constructor with the default Feign's encoder as a delegate.
*/
public SpringFormEncoder () {
this(new Encoder.Default());
}
/**
* Constructor with specified delegate encoder.
*
* @param delegate delegate encoder, if this encoder couldn't encode object.
*/
public SpringFormEncoder (Encoder delegate) {
super(delegate);
val processor = (MultipartFormContentProcessor) getContentProcessor(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)) {
super.encode(object, bodyType, template);
return;
}
val file = (MultipartFile) object;
val data = singletonMap(file.getName(), object);
super.encode(data, MAP_STRING_WILDCARD, template);
}
}從上面SpringFormEncoder的源碼上可以看到SpringFormEncoder類構造時把SpringManyMultipartFilesWriter實例添加到了處理器列表里了,但是在encode方法里又只判斷了MultipartFile類型,沒有判斷數組類型,這就比較奇怪了,底層有對數組的支持但上層卻缺少了相應判斷,而且在源碼里的test包里也沒有對文件數組類型的測試,難道只是encode方法里漏掉了?還是說那個文件數組的支持有問題?所以encode方法里才沒有加入對其的判斷?
于是我先試著對encode方法進行擴展加入對文件數組的判斷,應該就可以支持文件數組的上傳了,于是把SpringFormEncoder類源碼復制出來重命名為FeignSpringFormEncoder,源碼如下:
public class FeignSpringFormEncoder extends FormEncoder {
/**
* 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);
val processor = (MultipartFormContentProcessor) getContentProcessor(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 file = (MultipartFile) object;
val data = singletonMap(file.getName(), object);
super.encode(data, MAP_STRING_WILDCARD, template);
return;
} else if (bodyType.equals(MultipartFile[].class)) {
val file = (MultipartFile[]) object;
if(file != null) {
val data = singletonMap(file.length == 0 ? "" : file[0].getName(), object);
super.encode(data, MAP_STRING_WILDCARD, template);
return;
}
}
super.encode(object, bodyType, template);
}
}上述就是小編為大家分享的怎么在Spring Cloud中使用FeignClient實現文件上傳功能了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。