基于springcloud的feign单文件和多文件上传

本文介绍了如何在SpringCloud项目中利用Feign进行文件上传,包括单文件和多文件的处理。首先,添加必要的依赖,然后创建SpringMultipartEncoder配置类。在FeignClient中指定配置并使用@RequestPart注解处理文件参数。服务提供者端通过特定配置接收文件。注意,@RequestBody和@RequestPart不能同时用于同一方法参数,且文件数组需用@RequestPart注解处理。

1、首先说明一下,feign在传输的时候,其实就是和web端提交form表单是一样的道理,在官网上,feign是不支持文件传输的。但是在项目有这种需求,所有后来就出了两个feign的拓展依赖,在你要做文件传输的pom文件中加入如下两个依赖

<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>

2.依赖加完了,创建一个配置类SpringMultipartEncoder
代码如下

public class SpringMultipartEncoder extends FormEncoder {

    /**
     * Constructor with the default Feign's encoder as a delegate.
     */
    public SpringMultipartEncoder() {
        this(new Default());
    }


    /**
     * Constructor with specified delegate encoder.
     * @param delegate delegate encoder, if this encoder couldn't encode object.
     */
    public SpringMultipartEncoder(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 {
        // 单MultipartFile判断
        if (bodyType.equals(MultipartFile.class)) {
            MultipartFile file = (MultipartFile) object;
            Map data = Collections.singletonMap(file.getName(), object);
            super.encode(data, MAP_STRING_WILDCARD, template);
            return;
        } else if (bodyType.equals(MultipartFile[].class)) {
            // MultipartFile数组处理
            MultipartFile[] file = (MultipartFile[]) object;
            if(file != null) {
                Map data = Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), object);
                super.encode(data, MAP_STRING_WILDCARD, template);
                return;
            }
        }
        // 其他类型调用父类默认处理方法
        super.encode(object, bodyType, template);
    }


}

相应的包自己alt+enter就是。
3.然后在feignclient文件中加入如下代码

/**
     * 引用配置类MultipartSupportConfig.并且实例化
     */
    @Configuration
    public class FeignMultipartSupportConfig {

        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;

        @Bean
        public Encoder newsFeignEncoder() {
            return new SpringMultipartEncoder(new SpringEncoder(messageConverters));
        }
    }

这里这个newsFeignEncoder,根据你的业务可以自行命名。不同的feignclient可以定义不同的名字,只要你在引用的时候指明你当前的这个类部类就是,然后在@Feignclient注解后面加指明出上面的配置就是如下所示:

@FeignClient(name = "news-service", configuration = NewsClient.FeignMultipartSupportConfig.class, fallback = NewsClientFallback.class)

这是我的配置,这里对应上的就是configuration后面的,和你上面写的那个配置要对应上
到这里,配置基本完成了,但是还不能实现效果,
4.接下来是具体的例子了,在你需要做文件传输的feignclient中的方法上加入如下代码:

@PostMapping(value = "api/back/news/addNews",produces = {MediaType.APPLICATION_JSON_UTF8_VALUE},
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    boolean addNews(@RequestPart("file") MultipartFile file,
                    @RequestParam("newsTitle") String newsTitle,
                    @RequestParam("newsSource")String newsSource,
                    @RequestParam("newsBrief") String newsBrief,
                    @RequestParam("newsContent") String newsContent,
                    @RequestParam("cateId") int cateId);

主要起作用的是:produces和consumes,字面意思你就能看懂了,就是生产者和消费者的意思,还有需要注意的是,在传递文件的时候,file这个参数必须加@RequestPart注解,不然是不行的,在这里feign还有个需要注意的是,这里的方法里的参数的注解@RequestBody 和@RequestPart只能使用其中一个,如果你有文件又想传实体对象的话,那就只能把实体对象拆分成一个一个的属性传递了,而且这里每一个参数都需要加对应的注解,单个属性参数加@RequestParam注解。**如果要传递文件数组的话,直接写成@RequestPart(“file”) MultipartFile[] file这样就行。**到这里,服务消费者这边就写好了;接下来服务提供者那边也需要配置一个东西
5.在对应的方法上如下代码:

@RequestMapping(value = "addNews",method = RequestMethod.POST,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public boolean addNews(@RequestParam("file") MultipartFile file,
                           @RequestParam("newsTitle") String newsTitle,
                           @RequestParam("newsBrief") String newsBrief,
                           @RequestParam("newsContent") String newsContent,
                           @RequestParam("cateId") int cateId,
                           @RequestParam("newsSource")String newsSource)

服务提供者这边这样去接收就行了;这个配置,支持feign单文件和多文件上传
有问题的话,下面留言就行。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值