Feign使用MultipartFile参数

昨天同事发给我一个异常的截图,说是用@FeignClient上传文件时报错,我看了下方法的入参是MultipartFile,于是采坑开始(此处省略一万字,一万匹***奔涌而过,某度真LJ),参考网上技术文章,是因为feign不支持multipart/form类型,需要引入feign-form、feign-form-spring,于是在项目(spring-cloud:Greenwich.RELEASE)中引入feign-form:3.3.0feign-form-spring:3.3.0版本,但是不行啊,你文章里面说代码没问题,我这里就是不行,解决不了我自己的问题,还是需要自己来解决,没办法,看官方的介绍呗。

feign-form源码地址

Requirements

The feign-form extension depend on OpenFeign and its concrete versions:

  • all feign-form releases before 3.5.0 works with OpenFeign 9.* versions;
  • starting from feign-form's version 3.5.0, the module works with OpenFeign 10.1.0 versions and greater.

IMPORTANT: there is no backward compatibility and no any gurantee that the feign-form's versions after 3.5.0work with OpenFeign before 10.*. OpenFeign was refactored in 10th release, so the best approach - use the freshest OpenFeign and feign-form versions.

Notes:

  • spring-cloud-openfeign uses OpenFeign 9.* till v2.0.3.RELEASE and uses 10.* after. Anyway, the dependency already has suitable feign-form version, see dependency pom, so you don't need to specify it separately;
  • spring-cloud-starter-feign is a deprecated dependency and it always uses the OpenFeign's 9.* versions.

以上翻译过来大致意思如下:

feign-form扩展依赖于open-feign的特定版本

open-feign 9.*版本对应使用feign-from 3.5.0之前的版本

open-feign 10.1.0以及以后的版本对应使用3.5.0以及以后版本

feign-from 3.5.0之后的版本没有兼容open-feign 10.*之前的版本,10版本open-feign重构了代码,所以最好的方法是用最新的版本

spring-cloud-openfeign:2.0.3.release之前用open-feign 9.*版本 ,2.0.3.release之后的版本用open-feign 10.*,且在2.0.3.release 之后的版本里面已经包含feign-form的依赖,不需要再去指定相应的版本

spring-cloud-starter-feign已经不推荐使用,他一来的依然是open-feign 9.*

好了看完github上的介绍,又看了下项目的springcloud版本Greenwich.RELEASE,完全不需要任何其他的依赖了,已将包含了。

image-20200917111947527

接下来简单介绍配合spring-cloud正确的使用方法。

一、添加依赖

1.1、使用最新版本

<dependency>
    <groupId>io.github.openfeign.form</groupId>
    <artifactId>feign-form</artifactId>
    <version>3.8.0</version>
</dependency>
<!--配合spring使用-->
<dependency>
    <groupId>io.github.openfeign.form</groupId>
    <artifactId>feign-form-spring</artifactId>
    <version>3.8.0</version>
</dependency>

1.2、使用spring-cloud-starter-open-feign

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

二选一,如果想使用最新3.8.0版本,就使用1.1

二、服务提供者

MultipartFile 入参要用@RequestPart注解修饰,而不是@RequestParam,消费类型需指定为MediaType.MULTIPART_FORM_DATA_VALUE

/**
 * 文件上传控制器
 * @author DUCHONG
 * @since 2020-09-16 16:10
 **/
@RestController
@Slf4j
public class FileUploadController {


    /***
     * 上传文件
     * @param file
     * @return
     */
    @RequestMapping(value = "/fileUpload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("name") String name ) {
        // 判断文件是否为空
        if (!file.isEmpty()) {
            try {
                // 文件保存路径
                String filePath = System.getProperty("user.dir")+ "/upload/"
                        + file.getOriginalFilename();
                // 转存文件
                file.transferTo(new File(filePath));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        log.info("文件上传成功---fileName---{}",file.getOriginalFilename());
        return file.getOriginalFilename();
    }
}

三、Feign接口

@FeignClient 指定configuration参数

@Configuration
public class MultipartSupportConfig {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    @Primary
    @Scope("prototype")
    public Encoder feignEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }
}

MultipartFile 入参要用@RequestPart注解修饰,而不是@RequestParam

consumes消费类型需指定为MediaType.MULTIPART_FORM_DATA_VALUE

@FeignClient(value = "rest-provider",configuration = MultipartSupportConfig.class)
public interface FeignService {
    /**
     * 测试文件上传
     * @param file
     * @param name
     * @return
     */
    @RequestMapping(value = "/fileUpload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String uploadFile(@RequestPart("file") MultipartFile file, @RequestParam("name") String name);

四、服务消费者

/**
 * @author DUCHONG
 * @since 2019-03-25 16:25
 **/
@RestController
@Slf4j
public class FeignController {

    @Autowired
    private FeignService feignService;

    @RequestMapping(value = "/fileUpload")
    public String fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("name") String name ) {

        log.info("文件上传---fileName---{}",file.getOriginalFilename());
        return feignService.uploadFile(file,name);
    }

}

五、Postman来一发

image-20200917143146050

image-20200917143346782

搞定!!!
完整代码已上传至github

posted @ 2020-09-17 14:37  npe0  阅读(6701)  评论(2编辑  收藏  举报