Feign进行文件上传+表单调用
Feigin默认是不支持文件上传和表单提交的,需要做一些配置才能支持。
1、feign依赖
图中红色为form支持必须的jar。
2、添加自定义Encoder类:
- import java.lang.reflect.Type;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- import org.springframework.web.multipart.MultipartFile;
- import feign.RequestTemplate;
- import feign.codec.EncodeException;
- import feign.form.spring.SpringFormEncoder;
- import lombok.val;
- import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
- import static java.util.Collections.singletonMap;
- /**
- * @author roger yang
- * @date 10/22/2019
- */
- public class MultipartEncoder extends SpringFormEncoder {
- @SuppressWarnings("unchecked")
- @Override
- public void encode (Object object, Type bodyType, RequestTemplate template) throws EncodeException {
- if (bodyType.getClass().equals(ParameterizedTypeImpl.class) && ((ParameterizedTypeImpl) bodyType).getRawType().equals(Map.class)) {
- val data = (Map<String, Object>) object;
- Set<String> nullSet = new HashSet<>();
- for (Map.Entry<String, Object> entry : data.entrySet()) {
- if (entry.getValue() == null) {
- nullSet.add(entry.getKey());
- }
- }
- for (String s : nullSet) {
- data.remove(s);
- }
- super.encode(data, MAP_STRING_WILDCARD, template);
- return;
- } else if (bodyType.equals(MultipartFile.class)) {
- val file = (MultipartFile) object;
- val data = singletonMap(file.getName(), object);
- super.encode(data, MAP_STRING_WILDCARD, template);
- return;
- } else if (bodyType.equals(MultipartFile[].class)) {
- val file = (MultipartFile[]) object;
- if (file != null) {
- val data = singletonMap(file.length == 0 ? "" : file[0].getName(), object);
- super.encode(data, MAP_STRING_WILDCARD, template);
- return;
- }
- }
- super.encode(object, bodyType, template);
- }
- }
为什么要自定义呢?因为SpringFormEncoder这个类的源码里只对MultipartFile做了特殊处理,并未对MultipartFile[]数组进行处理,在传递多个文件时会报错。
- @Override
- public void encode (Object object, Type bodyType, RequestTemplate template) throws EncodeException {
- if (!bodyType.equals(MultipartFile.class)) {
- super.encode(object, bodyType, template);
- return;
- }
- val file = (MultipartFile) object;
- val data = singletonMap(file.getName(), object);
- super.encode(data, MAP_STRING_WILDCARD, template);
- }
另外,我们为了让文件和表单一起在http的body里一起传输,所有我们将他们都封装到map里统一处理。
3、feign接口类:
- import java.util.Map;
- import org.springframework.http.MediaType;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import com.longge.common.GlobalResponse;
- /**
- * @author: yangzhilong
- * @description: Notification api
- * post with MULTIPART_FORM_DATA_VALUE
- * you client feign config:
- * -------------------------------------------------------------------
- * import org.springframework.cloud.openfeign.FeignClient;
- import org.springframework.context.annotation.Bean;
- import com.longge.api.NotificationService;
- import feign.codec.Encoder;
- import com.longge.config.MultipartEncoder;
- @FeignClient(value = "notification-service", configuration = NotificationServiceFeign.FeignSimpleEncoderConfig.class)
- public interface NotificationServiceFeign extends NotificationMultipartService {
- class FeignSimpleEncoderConfig {
- @Bean
- public Encoder encoder(){
- return new MultipartEncoder();
- }
- }
- }
- * ---------------------------------------------------------------------
- * @date: 17:24 2019/7/3
- **/
- @RequestMapping(value = "/v1/api")
- public interface NotificationMultipartService {
- /**
- * common email channel ,use to send common email
- *
- * @param data
- * map key have:
- * attachfile --> MultipartFile[]
- * com.longge.dto.EmailDto.FieldName --- > value
- *
- * eg:
- * Map<String, Object> data = new HashMap<>();
- data.put("attachfile", new MultipartFile[] {file});
- data.put("from", emailDto.getFrom());
- data.put("to", emailDto.getTo());
- data.put("bodyText", emailDto.getBodyText());
- data.put("subject", emailDto.getSubject());
- * @return GlobalResponse<Long> email id
- */
- @RequestMapping(value = "/send_mail", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
- GlobalResponse<String> sendMail(Map<String, Object> data);
- }
其中为了支持 form请求,需要对此feign进行单独的配置:
- import org.springframework.cloud.openfeign.FeignClient;
- import org.springframework.context.annotation.Bean;
- import com.longge.api.NotificationMultipartService;
- import feign.codec.Encoder;
- @FeignClient(value = "notification-service", configuration = NotificationServiceFeign.FeignSimpleEncoderConfig.class)
- public interface NotificationServiceFeign extends NotificationMultipartService {
- class FeignSimpleEncoderConfig {
- @Bean
- public Encoder encoder() {
- return new MyEncoder();
- }
- }
- }
4、服务实现类
- @RequestMapping(value = "/v1/api/send_mail", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = {MediaType.APPLICATION_JSON_VALUE})
- public GlobalResponse<String> sendMail(@RequestParam(value = "attachfile", required = false) MultipartFile[] attachfile, EmailDto emailDto) {
- // TODO
- }
5、EmailDto属性
- private String from;
- private String to;
- private String subject;
- private String bodyText;
- private String bodyHtml;
感谢:https://blog.csdn.net/ytzzh0726/article/details/79731343
Feign进行文件上传+表单调用的更多相关文章
- 【Flask】 结合wtforms的文件上传表单
表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...
- 上传漏洞科普[1]-文件上传表单是Web安全主要威胁
为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...
- 原生js封装ajax:传json,str,excel文件上传表单提交
由于项目中需要在提交ajax前设置header信息,jquery的ajax实现不了,我们自己封装几个常用的ajax方法. jQuery的ajax普通封装 var ajaxFn = function(u ...
- Feign实现文件上传下载
Feign框架对于文件上传消息体格式并没有做原生支持,需要集成模块feign-form来实现. 独立使用Feign 添加模块依赖: <!-- Feign框架核心 --> <depen ...
- flask 文件上传(单文件上传、多文件上传)
文件上传 在HTML中,渲染一个文件上传字段只需要将<input>标签的type属性设为file,即<input type=”file”>. 这会在浏览器中渲染成一个文件上传字 ...
- ajax上传表单的俩种方式
1.用h5对象上传表单(图片) var formData = new FormData(); formData.append("authenticity_token", '1212 ...
- bootstrap上传表单的时候上传的数据默认是0 一定要小心
bootstrap上传表单的时候上传的数据默认是0 一定要小心
- spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)
一,表单中有多个文件域时如何实现说明和文件的对应? 1,说明和文件对应 文件上传页面中,如果有多个文件域又有多个相对应的文件说明时, 文件和说明如何对应? 我们在表单中给对应的file变量和text变 ...
- 使用ajax上传表单(带文件)
在使用form表单的时候上传文件+表单,会使得页面跳转,而在某些时候不希望跳转,只变化页面中的局部信息 通过查找资料,可以使用FormData进行ajax操作. FormData介绍:XMLHttpR ...
随机推荐
- Redis系列-第六篇哨兵模式
https://blog.csdn.net/niugang0920/article/details/97141175 Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋 ...
- springboot配置tomcat大全
server.tomcat.accept-count=100 # Maximum queue length for incoming connection requests when all poss ...
- Mock Server之接口信息从DB获取
上一篇,写了Mock Server的基础实现与被测系统的对接 当我们mock的接口信息.返回值等时不时维护时,都要在代码中编辑,那体验就不太好了,如果这些可以直接在浏览器编辑就好了. 因此对后端部分做 ...
- 逆向破解之160个CrackMe —— 021
CrackMe —— 021 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- python3 networkx
一.networkx 1.用于图论和复杂网络 2.官网:http://networkx.github.io/ 3.networkx常常结合numpy等数据处理相关的库一起使用,通过matplot来可视 ...
- httprunner学习5-参数化与数据驱动
前言 参数化是自动化测试离不开的话题,httprunner里面只要把上一篇声明变量学会了,参数化也就自然会了. 不同的地方在于声明变量时对应值只有一个,参数化是多个值,存放在list里面. httpr ...
- Ubuntu只读文件系统修复方法
首先备份重要数据 fsck.ext4 -p /dev/sdb5 reboot
- 最小球覆盖——模拟退火&&三分套三分套三分
题目 给出 $N(1 \leq N \leq 100)$ 个点的坐标 $x_i,y_i,z_i$($-100000 \leq x_i,y_i,z_i \leq 100000$),求包围全部点的最小的球 ...
- Longest Common Substring SPOJ - LCS (后缀自动机)
Longest Common Substring \[ Time Limit: 294ms \quad Memory Limit: 1572864 kB \] 题意 给出两个串,求两个串的最长公共连续 ...
- cc2530中单片机的通用I/O接口
cc2530中有21个输入/输出引脚. 这些引脚可以设置为通用I/O或者设置为外设I/O.(其实这里的外设还是不太懂到底指什么,网上说输入设备,但是通用I/O也可以输入啊,为什么要弄外设I/O?) 其 ...