好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Feign之Multipartfile文件传输填坑

Multipartfile文件传输

1. 添加依赖

?

1

2

3

4

5

6

7

8

9

10

< dependency >

       < groupId >io.github.openfeign.form</ groupId >

         < artifactId >feign-form</ artifactId >

         < version >3.3.0</ version >

     </ dependency >

     < dependency >

         < groupId >io.github.openfeign.form</ groupId >

         < artifactId >feign-form-spring</ artifactId >

         < version >3.3.0</ version >

     </ dependency >

2. 添加配置类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

@Configuration

public class FeignMultipartConfig {

     @Bean

     @Primary

     @Scope ( "prototype" )

     public SpringFormEncoder multipartFormEncoder() {

         return new SpringFormEncoder();

     }

     @Bean

     public feign.Logger.Level multipartLoggerLevel() {

         return feign.Logger.Level.FULL;

     }

}

3. 接口编写

@FeignClient使用配置类

@PostMapping设置

?

1

consumes = MediaType.MULTIPART_FORM_DATA_VALUE

使用@RequestPart(),不能使用@RequestParam()

?

1

2

3

4

5

@FeignClient (value = "face-service" ,configuration = FeignMultipartConfig. class )

public interface FaceClient {

  @PostMapping (value = "/search/student" , consumes = MediaType.MULTIPART_FORM_DATA_VALUE)

     ResponseBase<SearchStudentFaceVO> searchStudentFace( @RequestPart ( "file" ) MultipartFile file);

}

feign不能正常传递参数MultipartFile(文件)的解决

之前工作中有个业务场景:需要把文件以MultipartFile进行服务之间的调用(使用的是Feign),特此记录下踩到的坑

需要注意的是:使用默认的springcloud自带的spring-cloud-starter-openfeign是不支持传递文件的。

我看网上有很多使用feign-form和feign-form-spring支持的jar包,然后配置SpringFormEncoder,但我试了,没有成功,最后使用了另外一种方法,在此记录下吧:

方法一:使用外部依赖

?

1

2

3

4

5

6

7

8

9

10

11

< dependency >

            < groupId >io.github.openfeign.form</ groupId >

            < artifactId >feign-form</ artifactId >

            < version >3.3.0</ version >

        </ dependency >

 

        < dependency >

            < groupId >io.github.openfeign.form</ groupId >

            < artifactId >feign-form-spring</ artifactId >

            < version >3.3.0</ version >

        </ dependency >

新建配置类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

package com.jsyd.ict.ictservicemanager.configuration;

import org.springframework.beans.factory.ObjectFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;

import org.springframework.cloud.openfeign.support.SpringEncoder;

import org.springframework.context.annotation.Bean;

import feign.codec.Encoder;

import feign.form.spring.SpringFormEncoder;

import org.springframework.context.annotation.Configuration;

/**

  * 处制定了注入的feignFormEncoder可以覆盖掉原本的encoder

  * 该方式可以让发送multipartFile成为可能

  * @author wangyang

  * @version 1.0

  * @date 2021/4/13 19:13

  */

@Configuration

public class MultipartSupportConfig {

     @Autowired

     private ObjectFactory<HttpMessageConverters> messageConverters;

     @Bean

     public Encoder feignFormEncoder() {

         return new SpringFormEncoder( new SpringEncoder(messageConverters));

     }

}

配置feign接口:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package com.jsyd.ict.ictservicemanager.feign;

import com.jsyd.ict.ictservicemanager.util.resp.RespUtil;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.http.MediaType;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.InputStream;

/**

  * 能力的调用

  *

  * @author wangyang

  * @version 1.0

  * @date 2021/3/11 21:01

  */

@FeignClient (name = "ict-service-capacity" , configuration = MultipartSupportConfig. class )

public interface CapacityFeign {

     @RequestMapping (value = "contentAudit/baiduImgAuditByFile" , method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)

     RespUtil baiduImgAuditByFile( @RequestPart (value = "file" ) MultipartFile file);

}

注意:文件的传输需要使用@RequestPart()注解

服务端:

?

1

2

3

4

5

   @RequestMapping (value = "/baiduImgAuditByFile" , method = RequestMethod.POST)

   public RespUtil baiduImgAuditByFile( @RequestParam ( "file" ) MultipartFile file)  {

// 调用service

       return null ;

   }

结果发现,这样是获取不到结果的,研究了好一会,因为要着急联调,就没有继续跟踪了,有时间在深入研究下。

后来使用了下面的方法,成功传参

方法二:使用HttpServletRequest获取

上述操作都不需要,即:不需要导入依赖,也不需要创建文件,只需要在服务端通过HttpServletRequest去设置

使用HttpServletRequest设置:

伪代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@RequestMapping (value = "/baiduImgAuditByFile" , method = RequestMethod.POST)

public RespUtil baiduImgAuditByFile(MultipartFile file, HttpServletRequest request) {

     if (file == null ) {

         // 解决服务间调用无法接受MultipartFile参数的问题

         String contentType = request.getContentType();

         if (contentType != null && contentType.toLowerCase().startsWith( "multipart/" )) {

             MultipartHttpServletRequest multipartRequest =

                     WebUtils.getNativeRequest(request, MultipartHttpServletRequest. class );

             if (multipartRequest != null ) {

                 MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();

                 for (Map.Entry<String, List<MultipartFile>> entry : multiFileMap.entrySet()) {

                     file = entry.getValue().get( 0 );

                 }

             }

         }

     }

     // 处理业务逻辑

     return null ;

}

主要说明如下图:

即通过HttpServletRequest 的方式即使文件获取不到,也可以进行特殊处理,从而获取文件。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_36325121/article/details/89004092

查看更多关于Feign之Multipartfile文件传输填坑的详细内容...

  阅读:20次