栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

openFeign转发请求头引发的问题java.lang.IllegalArgumentException: Invalid character found in method name [XXXX]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

openFeign转发请求头引发的问题java.lang.IllegalArgumentException: Invalid character found in method name [XXXX]

OpenFeign,服务间调用的请求头转发过程要小心content-length

当下主流的分布式框架中,涉及到的服务之间的调用,有多种方案;我采用的是使用OpenFeign
,服务间的调用往往就涉及到请求头中一些参数的转发,常见例如:访问令牌;接下来,就是我在实际使用过程中对于请求头转发的处理和碰到问题的描述,相应的解决方式,希望能够为一些人提供借鉴。

  1. 请求头转发 处理
@Configuration
public class FeignConfig {
	// feign的日志级别配置
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
	//让DispatcherServlet向子线程传递RequestContext
    @Bean
    public ServletRegistrationBean dispatcherRegistration(DispatcherServlet servlet) {
        servlet.setThreadContextInheritable(true);
        return new ServletRegistrationBean<>(servlet, "/**");
    }
	//覆写拦截器,在feign发送请求前取出原来的header并转发,问题就是出现在复制之后
    @Bean
    public RequestInterceptor requestInterceptor() {
        return (template -> {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //获取请求头
            Enumeration headerNames = request.getHeaderNames();
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String name = headerNames.nextElement();
                    String value = request.getHeader(name);
                    //直接复制请求头到模板
                     template.header(name, value);
                }
            }
        });
    }
  1. 出现的问题
    A服务调用B服务时,在服务B上出现如下问题:
java.lang.IllegalArgumentException: Invalid character found in method name [XXXX]. HTTP method names must be tokens
  1. 解决方式
    我首先先把feign间的调用日志全部打开,在控制台去看日志,果然发现了问题所在,所以开发一定要仔细去看日志,也学会去看日志,即使不知道怎么下手解决问题,能定位到问题就能更精准找到解决方案
    如下图:

    通过观察,发现了请求头有两个content-length,而且大小不一致;所以问题就是出在这个地方上,因为前端通过Ajax 提交会把content-length 带上来,在第1点中的拦截器中,又会把参数复制一遍,因此出现了两个content-length,其他如果有类似参数也会有此可能;所以最终解决的方式是在拦截器中把这个参数剔除,不做此项参数复制
    @Bean
    public RequestInterceptor requestInterceptor() {
        return (template -> {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            Enumeration headerNames = request.getHeaderNames();
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String name = headerNames.nextElement();
                    String value = request.getHeader(name);
                    // 剔除content-length的复制
                    if (!"content-length".equalsIgnoreCase(name)) {
                        template.header(name, value);
                    }
                }
            }
        });
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/671370.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号