1 故事背景

  • 最近项目上有个业务需求,翻译成技术需求,即:将request.headers中的几个header入参转换成request.body(pageRequest)中的内置参数。

为便于灵活配置,header 参数名称是动态可配置的(存放于nacos配置中心),比如:sysCodeAccept-Language

  • 技术实现,主要就 springmvcorg.springframework.web.bind.WebDataBinder ,并结合 javax.servlet.http.HttpServletRequest,实现将header中的指定参数转发至request.body(pageRequest).params

核心代码如下:

@RestController("cn.johnnyzen.bd.dataservice.biz.dataservice.controller.v2.CommonSearchController")
@Validated
@Api(tags = "DATA2API Controller # V2")
public class CommonSearchController implements DataServiceOpenApi { // ... @Autowired
private ServiceConfig serviceConfig; // ... @InitBinder
public void forwardedHeadersToParamsDataBinder(WebDataBinder binder, HttpServletRequest request) {
//判断是否启用本特性
ForwardedHeaders forwardedHeaders = serviceConfig.getForwardedHeaders();
if(ObjectUtils.isEmpty(forwardedHeaders) || forwardedHeaders.getEnable().equals(Boolean.FALSE)){
logger.warn("Fail to forward headers to body's params because that `service-config.forwardedHeaders` be empty or not enabled!");
return ;
}
logger.info("Start to forward request's headers to request body params with `service-config.forwardedHeaders`,config data as follows : \n{}", forwardedHeaders); //获取被绑定对象----PageRequest
PageRequest<Map<String,Object>> pageRequest = (PageRequest<Map<String, Object>>) binder.getTarget();
if(ObjectUtils.isEmpty(pageRequest) || ObjectUtils.isEmpty(pageRequest.getParams())){
logger.error("`request.body(pageRequest)` or `request.body(pageRequest).params` is empty!");
return;
}
Map<String,Object> dynamicParams = pageRequest.getParams(); List<ForwardHeaderToParamConfig> forwardHeaderToParamConfigList = forwardedHeaders.getHeaders();
forwardHeaderToParamConfigList.stream().forEach(forwardedHeaderConfig -> {
//获取目标header参数值,并转发至params中
String headerName = forwardedHeaderConfig.getHeader();
String headerValue = request.getHeader( forwardedHeaderConfig.getHeader() );
String paramName = forwardedHeaderConfig.getParam();
logger.debug("headerName:{}, headerValue:{}, paramName:{}", headerName, headerValue, paramName);
dynamicParams.put(paramName, headerValue);
});
} // ...
}
  • 那么,我写这篇博客的目的是什么呢?
  • 你有没有这么一个疑惑:request.getHeader(headerName),这个基于Tomcat.catalina实现的方法,是否区分headerName的大小写?

如果不区分大小写,那还好办;如果区分大小写,就尴尬了————我将需要将Accept-Language的每一种字母大小写的可能性都要一一进行配置!

经过源码分析,答案是:request.getHeader(headerName)不区分大小写

感兴趣的朋友,可以进入第2章节,一起看看源码

2 源码分析

  • springmvc: 5.2.15.RELEASE
  • springboot: 2.3.12.RELEASE
  • tomcat-embed: 9.0.46 (springboot内嵌的tomcat)
  • 调试工具: IDEA

Step1 javax.servlet.http.HttpServletRequest : request.getHeader("Accept-Language")

import javax.servlet.http.HttpServletRequest;

//...
request.getHeader("Accept-Language")
//...

Step2 javax.servlet.http.HttpServletRequest#getHeader

javax.servlet.http.HttpServletRequest#getHeader

Step3 org.apache.catalina.connector.Request#getHeader

特别说明:org.apache.catalina.connector.Request#getHeader 其实现了接口:javax.servlet.http.HttpServletRequest#getHeader

org.apache.catalina.connector.Request#getHeader

Step4 org.apache.coyote.Request#getHeader

org.apache.coyote.Request#getHeader

Step5 org.apache.tomcat.util.http.MimeHeaders#getHeader

org.apache.tomcat.util.http.MimeHeaders#getHeader

Step6 org.apache.tomcat.util.http.MimeHeaders#getValue(java.lang.String)

org.apache.tomcat.util.http.MimeHeaders#getValue(java.lang.String)

[Servlet/Tomcat] HttpServletRequest#getHeader(headerNameWithIgnoreCase)(获取header时不区分大小写)的更多相关文章

  1. servlet获取参数时,request.getParameter("id")参数获取失败

    servlet获取参数时,request.getParameter("id")参数获取失败,这里的参数是“index”里面href中的参数 要注意,取不到值,是不是要取的参数有没有 ...

  2. 编译时提示软件包 javax.servlet.http 不存在 import javax.servlet.http.HttpServletRequest;

    编译时错误:软件包 javax.servlet.http 不存在import javax.servlet.http.HttpServletRequest; 解决办法:把servlet-api.jar加 ...

  3. servlet中使用request.getHeader("referer")获取页面从哪跳转过来的

    问题 servlet中使用request.getHeader("referer")获取页面从哪跳转过来的,利用这个方法可以判断网页是否正常登录.我做了一个javaweb小项目,其中 ...

  4. JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...

  5. (转)JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...

  6. 在Myeclipse buildpath 加server lib (server runtime)/项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved

    来源于:http://blog.csdn.net/dingqinghu/article/details/8805922 http://yl-fighting.iteye.com/blog/140946 ...

  7. Servlet+Tomcat制作出第一个运行在Tomcat上的Java应用程序

    转载自:http://www.linuxidc.com/Linux/2011-08/41685.htm [日期:2011-08-27] 来源:csdn  作者:Cloudyxuq     1.IDE工 ...

  8. 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  9. Servlet学习(二):ServletConfig获取参数;ServletContext应用:请求转发,参数获取,资源读取;类装载器读取文件

    转载:http://www.cnblogs.com/xdp-gacl/p/3763559.html 一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件 ...

  10. Java-API:javax.servlet.http.HttpServletRequest

    ylbtech-Java-API:javax.servlet.http.HttpServletRequest 1.返回顶部 1. javax.servlet.http Interface HttpSe ...

随机推荐

  1. RStuido Server 选择不同的 R 版本(conda 中的不同 R 版本)

    自从上一次服务器重装系统之后,总感觉缺少了一些东西,安装R包很多依赖库报错,也可以解决,但总是存在,烦. 一天,一个同事问我说ggpubr包安装不成功,我就自己试了一下,真的是--安装不成功. 当你到 ...

  2. 一次有关 DNS 解析导致 APP 慢的问题探究

    目录 一.业务背景 二. 问题 三.问题排查 3.1.问题一: 基于DNS 延迟的解析 3.2.问题二:HTTPDNS侧 HTTPDNS基础理论 相关问题 四.优化方向 4.1.域名解析配置 4.2. ...

  3. 消失的死锁:从 JSF 线程池满到 JVM 初始化原理剖析

    一.问题描述 在一次上线时,按照正常流程上线后,观察了线上报文.接口可用率十分钟以上,未出现异常情况,结果在上线一小时后突然收到jsf线程池耗尽的报警,并且该应用一共有30台机器,只有一台机器出现该问 ...

  4. 浅谈 thinkphp composer 扩展包加载原理

    浅谈 thinkphp composer 扩展包加载原理 本文将介绍 ThinkPHP 中 Composer 扩展包的加载原理,帮助读者更好地理解和应用该功能. 前言 如题,今天感觉好久没有更新博客了 ...

  5. StencilJs学习之事件

    其实并没有所谓的 stencil Event,相反 stencil 鼓励使用 DOM event.然而,Stencil 提供了一个 API 来指定组件可以触发的事件,以及组件监听的事件. 这是通过 E ...

  6. GPU技术在大规模数据集处理和大规模计算中的应用

    目录 GPU 技术在大规模数据集处理和大规模计算中的应用 随着深度学习在人工智能领域的快速发展,大规模数据处理和大规模计算的需求日益增长.GPU(图形处理器)作为现代计算机的重要部件,被广泛应用于这些 ...

  7. 数仓性能调优:大宽表关联MERGE性能优化

    摘要:本文主要为大家讲解在数仓性能调优过程中,关于大宽表关联MERGE性能优化过程. 本文分享自华为云社区<GaussDB(DWS)性能调优:大宽表关联MERGE性能优化>,作者:譡里个檔 ...

  8. Containerd组件 —— containerd-shim-runc-v2作用

    1.概述 通过<浅析开源容器标准--OCI>.<浅析容器运行时>和<浅析Kubernetes CRI>这三篇博文我们了解了容器标准OCI.容器运行时以及Kubern ...

  9. .net core提示502.5错误

    最近给WindowsServer2012服务器部署.Net Core项目,部署后一直显示502.5错误,具体如下: 网上找了一大堆解决办法都行不通,最后在stackoverflow中找到说是缺少一个补 ...

  10. 前端查询天气的html

    <html> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script&g ...