溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Spring Cloud中使用FeignClient實(shí)現(xiàn)文件上傳功能

發(fā)布時(shí)間:2021-05-27 17:56:47 來(lái)源:億速云 閱讀:170 作者:Leah 欄目:編程語(yǔ)言

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)怎么在Spring Cloud中使用FeignClient實(shí)現(xiàn)文件上傳功能,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

具體的使用方法是加入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接口里方法參數(shù)是文件類型的要用@RequestPart注解,且要設(shè)置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);

但遇到一個(gè)問(wèn)題,就是不支持文件數(shù)組類型,我看了源碼,發(fā)現(xiàn)源碼里底層是有對(duì)MultipartFile[]類型的支持的,源碼中有個(gè)類叫SpringManyMultipartFilesWriter,是專門針對(duì)文件數(shù)組類型進(jìn)行操作的,但是配置到項(xiàng)目里的SpringFormEncoder類里卻沒(méi)有對(duì)文件數(shù)組類型的判斷,以致不能支持文件數(shù)組的上傳.。

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類構(gòu)造時(shí)把SpringManyMultipartFilesWriter實(shí)例添加到了處理器列表里了,但是在encode方法里又只判斷了MultipartFile類型,沒(méi)有判斷數(shù)組類型,這就比較奇怪了,底層有對(duì)數(shù)組的支持但上層卻缺少了相應(yīng)判斷,而且在源碼里的test包里也沒(méi)有對(duì)文件數(shù)組類型的測(cè)試,難道只是encode方法里漏掉了?還是說(shuō)那個(gè)文件數(shù)組的支持有問(wèn)題?所以encode方法里才沒(méi)有加入對(duì)其的判斷?

于是我先試著對(duì)encode方法進(jìn)行擴(kuò)展加入對(duì)文件數(shù)組的判斷,應(yīng)該就可以支持文件數(shù)組的上傳了,于是把SpringFormEncoder類源碼復(fù)制出來(lái)重命名為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實(shí)現(xiàn)文件上傳功能了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI