依赖
<!--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
文件流传到邮件服务发送,需要代码构建MultipartFile
,DiskFileItemFactory
,这个时候要注意FeildName
填写的就是attachment
。SpringFormEncoder
不可以少,两种方式都用了它的。- 请求方式为
post
,get
会报错