使用OpenFeign远程调用时请求头处理报错问题
1. 错误信息
basic.result.exception.OtherException: feign error:系统异常:Content type 'multipart/form-data;boundary=--------------------------679449061975336133574827;charset=UTF-8' not supported.请联系管理员
at com.assembly.oauth.web.exception.auth.FeignErrorDecoder.decode(FeignErrorDecoder.java:26)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy191.addStationModelList(Unknown Source)
at com.assembly.dg.online.controller.TestController.importStation(TestController.java:326)
at com.assembly.dg.online.controller.TestController$$FastClassBySpringCGLIB$$1.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
at com.assembly.dg.online.controller.TestController$$EnhancerBySpringCGLIB$$1.importStation(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.assembly.oauth.web.authorization.interceptor.CrossFilter.doFilter(CrossFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:96)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:41002)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
2. 使用场景以及问题出现的原因
在本地微服务中使用Spring MVC 上传文件时, 因为使用了MultipartFile 对象接受, 所以前端设置 请求头"Content-type"为multipart/form-data; ,这在本地 微服务中是没有问题的,
但是在处理请求的过程中, 使用了OpenFeign 远程调用了 其他的微服务保存信息, 就有问题了,
@RequestMapping(value = "importStation")
@NoAuthorization
public void importStation(MultipartFile file, HttpServletRequest request) throws IOException {
// ... 业务处理
// RPC远程调用 保存信息
dgRpcRemote.addStationModelList(stationModelList);
}
本项目中使用的是OpenFeign进行远程调用, 为了在调用时,可以携带调用方的请求头信息,例如token等等, 项目中自定义了一个拦截器进行处理:
@Component
public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
public FeignBasicAuthRequestInterceptor() {
}
public void apply(RequestTemplate requestTemplate) {
try {
//获取 ThreadLocal中的 本地Request对象
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
String type;
String tenantCode;
if (headerNames != null) {
// 全盘拷贝过去
while(headerNames.hasMoreElements()) {
type = (String)headerNames.nextElement();
tenantCode = request.getHeader(type);
requestTemplate.header(type, new String[]{tenantCode});
}
}
type = TenantContextHolder.getAuthorizationType();
if (StringUtils.isNotBlank(type)) {
requestTemplate.header("tenantAuthorization", new String[]{type});
}
tenantCode = TenantContextHolder.getTenantCode();
if (StringUtils.isNotBlank(tenantCode)) {
requestTemplate.header("tenantCode", new String[]{tenantCode});
}
String tokenId = TenantContextHolder.getTokenId();
if (StringUtils.isNotBlank(tokenId)) {
requestTemplate.header("tenantToken", new String[]{tokenId});
}
requestTemplate.header("Content-Type", new String[]{"application/json;charset=UTF-8"});
} catch (Exception var8) {
var8.printStackTrace();
}
}
}
只需实现 接口RequestInterceptor 并被Spring扫描到即可,OpenFeign会自动调用,此类重写的 apply 方法中就 将本地的请求Request对象的请求头全部拷贝到 新的请求中用于调用,这样multipart/form-data; 也就拷贝了过去,但是在RPC 调用的接受方,确只是普通的 Rest 接口, 需要的是application/json ,所以就报了上述错误.
如果项目中在使用Feign进行远程调用,并有需要进行请求头传递的需求,可以参考此方式
3. 解决方式
因为在拦截器中获取的是 ThreadLocal 中保存的本地 请求Request 信息,所以 只需保证 在调用时不在请求所在线程即可:
new Thread(() ->dgRpcRemote.addStationModelList(stationModelList) ).start();
在调用时另启动一个线程进行调用即可, 如果有更好的方式,欢迎指教
使用OpenFeign远程调用时请求头处理报错问题的更多相关文章
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
C#编译器优化那点事 使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...
- java调用本地方法的时候报错 could not find the main class:xx.program will exit
如图所示,当在java调用本地方法的时候报错 我的解决办法是把dll文件放到System.out.println(System.getProperty("java.library.path& ...
- 安装php时,make步骤报错make: *** [ext/gd/gd.lo] Error 1
安装PHP时,make步骤报错make: *** [ext/gd/gd.lo] Error 1 /usr/local/src/LAMP+memcahed+catci/php-5.4.0/ext/gd/ ...
- vue项目初始化时npm run dev报错webpack-dev-server解决方法
vue项目初始化时npm run dev报错webpack-dev-server解决方法 原因:这是新版webpack存在的BUG,卸载现有的新版本webpack,装老版本就好webpack-dev- ...
- python踩坑系列之导入包时下划红线及报错“No module named”问题
python踩坑系列之导入包时下划红线及报错“No module named”问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下(fileshand ...
- Python模块学习之xlrd 读取Excel时传入formatting_info=True报错:NotImplementedError: formatting_info=True not yet implemented
问题:xlrd读取Excel时传入 formatting_info=True 报错 之前我们使用读取xls文件的时候都是使用的xlrd库,但是这个库只能操作 .xls格式,对于后来的 .xlsx的版本 ...
- webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错:
webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错. 原因是: 局部变量ip跟全局变量冲突的问题,可以将局部变量重新命名一下,就可以通过编译了. aec_rdft.c修改以后文件代 ...
- OpenFeign远程调用原理
之前对OpenFeign 了解到只用在接口上面打个注解,然后就可以通过内部调用去调用远程地址.研究完Feign生成对象以及代理对象的作用过程之后发现这个过程用到了Spring的好多东西,在之后的过程中 ...
- 使用Java的URL/HttpURLConnection进行远程调用(POST请求)
利用Java的HttpURLConnection进行远程url请求(调用远程接口) 测试类:请求类型为json,以post方式请求,利用OutputStream写入数据 实体类: public cla ...
- RestTemplate远程调用POST请求:HTTP 415 Unsupported Media Type
这是本项目的接口 称为client @POST @Path("/{urlcode}") @Consumes(MediaTypes.JSON_UTF_8) @Produces(Med ...
随机推荐
- 【记录一个问题】gin框架中,ShouldBindUri()函数依赖特定版本编译器,更换库的版本号后导致panic
panic发生在这一行: uriBindErr = c.ShouldBindUri(methodLastInParam.Interface()) 导致panic的堆栈信息如下: err=reflect ...
- 【K哥爬虫普法】老铁需要车牌靓号吗?判刑的那种
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...
- 8.3 C++ 定义并使用类
C/C++语言是一种通用的编程语言,具有高效.灵活和可移植等特点.C语言主要用于系统编程,如操作系统.编译器.数据库等:C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统.图形用户界面 ...
- HT UI 5.0,前端组件图扑是认真的
为顺应数字时代的不断发展,图扑 HT UI 5.0 在原有功能强大的界面组件库的基础上进行了全面升级,融入了更先进的技术.创新的设计理念以及更加智能的功能.HT UI 5.0 使用户体验更为直观.个性 ...
- 利用Docker、云服务器、mongodb搭建自己的测试平台
准备一个云服务器 购买一个云服务器,在阿里云,腾讯云上购买即可. 然后创建一个实例,安装Linux操作系统,我安装的是CentOS. 记住账号和密码,可以使用ssh远程登录即可. 搭建测试环境 D ...
- 架构设计脱胎换骨!英特尔酷睿Ultra深度解析
英特尔正式发布了第一代酷睿Ultra处理器平台,也就是首个基于Intel 4制程工艺(7nm)打造的移动级处理器平台,其核心代号为Meteor Lake,产品系列贴标设计也采用了全新方案. 同时在命名 ...
- Idhttp Post https 连接 报“IOHandler value is not valid.”错误
今天研究阿里巴巴的对接,发现IDHTTP 的post 如果是 https 的连接就会报:"IOHandler value is not valid."错误 加载https的站点页面 ...
- DNS正向解析
实验介绍:正向解析 通常把域名到IP称为正向解析 把ip到域名称为反向解析 一:前期准备 准备一台客户端测试正向解析是否正常 修改ip 子网掩码 DNS服务器 使用VMnet8 IP要和DNS服务器端 ...
- 【CAS学习一】CAS服务端部署
公司要做单点登录系统,网上搜了一下目前主流方案是CAS,故部署一个试试看. 1.下载 因为最近出现log4j2远程代码执行漏洞,尽量选择新版本已修复此漏洞的,故CAS选择6.4版本.打包部署依赖JDK ...
- 【scikit-learn基础】--模型持久化
模型持久化(模型保存与加载)是机器学习完成的最后一步.因为,在实际情况中,训练一个模型可能会非常耗时,如果每次需要使用模型时都要重新训练,这无疑会浪费大量的计算资源和时间. 通过将训练好的模型持久化到 ...