微服务feign远程调用传输文件

2022-07-27 13:29:33

依赖

<!--SpringCloud openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.6.RELEASE</version></dependency><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.6.RELEASE</version></dependency><!-- SpringBoot整合Web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.2.RELEASE</version></dependency>

服务接口端

//图片上传@PostMapping(value="/upload",consumes=MediaType.MULTIPART_FORM_DATA_VALUE)publicResultupload(@RequestPart("imgFile")MultipartFile imgFile){........}

注意加上consumes = MediaType.MULTIPART_FORM_DATA_VALUE)和@RequestPart注解

Feign调用端

packagecom.zhubayi.backend.feign;importcom.zhubayi.backend.config.MultipartSupportConfig;importcom.zhubayi.common.entity.Result;importcom.zhubayi.common.pojo.Setmeal;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;/**
 * @author zhubayi
 */@FeignClient(name="health-provider")publicinterfaceSetmealFeignService{@PostMapping(value="/setmeal/upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE)Resultupload(@RequestPart("imgFile")MultipartFile imgFile);}

注意加上consumes = MediaType.MULTIPART_FORM_DATA_VALUE)和@RequestPart注解

Feign调用端还要向容器注入SpringFormEncoder

@BeanpublicEncoderfeignFormEncoder(){returnnewSpringFormEncoder();}

在这里插入图片描述

这种方式当传输的非文件类型的时候会报错,采用下面的方式可以解决。

第二种方式

新建配置在远程调用feign端加上类MultipartSupportConfig

packagecom.zhubayi.backend.config;importfeign.codec.Encoder;importfeign.form.spring.SpringFormEncoder;importorg.springframework.beans.factory.ObjectFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.autoconfigure.http.HttpMessageConverters;importorg.springframework.cloud.openfeign.support.SpringEncoder;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/**
 * @author zhubayi
 */@ConfigurationpublicclassMultipartSupportConfig{@AutowiredprivateObjectFactory<HttpMessageConverters> messageConverters;//微服务传输文件用@BeanpublicEncoderfeignFormEncoder(){returnnewSpringFormEncoder(newSpringEncoder(messageConverters));}}

在远程调用端@FeignClient加上
configuration = MultipartSupportConfig.class

packagecom.zhubayi.backend.feign;importcom.zhubayi.backend.config.MultipartSupportConfig;importcom.zhubayi.common.entity.Result;importcom.zhubayi.common.pojo.Setmeal;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;/**
 * @author zhubayi
 */@FeignClient(name="health-provider",configuration=MultipartSupportConfig.class)publicinterfaceSetmealFeignService{@PostMapping(value="/setmeal/upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE)Resultupload(@RequestPart("imgFile")MultipartFile imgFile);@PostMapping(value="/setmeal/add")Resultadd(@RequestBodySetmeal setmeal,@RequestParam("checkgroupIds")Integer[] checkgroupIds);}

注意加上consumes = MediaType.MULTIPART_FORM_DATA_VALUE)和@RequestPart注解

服务端

packagecom.zhubayi.provider.controller;importcom.zhubayi.common.constant.MessageConstant;importcom.zhubayi.common.entity.Result;importcom.zhubayi.common.pojo.Setmeal;importcom.zhubayi.common.utils.QiniuUtils;importcom.zhubayi.provider.service.SetmealService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.util.UUID;/**
 * @author zhubayi
 * 套餐管理
 */@RestController@RequestMapping("/setmeal")publicclassSetmealController{@AutowiredprivateSetmealService setmealService;//图片上传@PostMapping(value="/upload",consumes=MediaType.MULTIPART_FORM_DATA_VALUE)publicResultupload(@RequestPart("imgFile")MultipartFile imgFile){try{//获取原始文件名String originalFilename= imgFile.getOriginalFilename();int lastIndexOf= originalFilename.lastIndexOf(".");//获取文件后缀String suffix= originalFilename.substring(lastIndexOf-1);//使用UUID随机产生文件名称,防止同名文件覆盖String fileName= UUID.randomUUID().toString()+ suffix;QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName);//图片上传成功Result result=newResult(true,MessageConstant.PIC_UPLOAD_SUCCESS);
            result.setData(fileName);return result;}catch(Exception e){
            e.printStackTrace();//图片上传失败returnnewResult(false,MessageConstant.PIC_UPLOAD_FAIL);}}//新增@PostMapping("/add")publicResultadd(@RequestBodySetmeal setmeal,Integer[] checkgroupIds){System.out.println(checkgroupIds);System.out.println(setmeal);//        try {//            setmealService.add(setmeal,checkgroupIds);//        }catch (Exception e){//            //新增套餐失败//            return new Result(false,MessageConstant.ADD_SETMEAL_FAIL);//        }//新增套餐成功returnnewResult(true,MessageConstant.ADD_SETMEAL_SUCCESS);}}

注意加上consumes = MediaType.MULTIPART_FORM_DATA_VALUE)和@RequestPart注解

特别注意几点:

  • consumes = MediaType.MULTIPART_FORM_DATA_VALUE 必须存在
  • 文件部分注解为@RequestPart,要不然出现错误:the request was rejected because no multipart boundary was found
  • attachment为传过来的文件的name的值。不可以随意更改。要不然出现错误:Required request part 'file' is not present,有时候我们需要将文件流转成MultipartFile。比如:我们有时候需要导出EXCEL发邮件,但是发邮件有专门的服务时,就需要将EXCEL文件流传到邮件服务发送,需要代码构建MultipartFileDiskFileItemFactory,这个时候要注意FeildName填写的就是attachment
  • SpringFormEncoder 不可以少,两种方式都用了它的。
  • 请求方式为postget会报错
  • 作者:胡八一
  • 原文链接:https://blog.csdn.net/qq_44732146/article/details/119431163
    更新时间:2022-07-27 13:29:33