[Servlet/Tomcat] HttpServletRequest#getHeader(headerNameWithIgnoreCase)(获取header时不区分大小写)
1 故事背景
- 最近项目上有个业务需求,翻译成技术需求,即:将
request.headers中的几个header入参转换成request.body(pageRequest)中的内置参数。
为便于灵活配置,header 参数名称是动态可配置的(存放于nacos配置中心),比如:
sysCode、Accept-Language
- 技术实现,主要就
springmvc的org.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时不区分大小写)的更多相关文章
- servlet获取参数时,request.getParameter("id")参数获取失败
servlet获取参数时,request.getParameter("id")参数获取失败,这里的参数是“index”里面href中的参数 要注意,取不到值,是不是要取的参数有没有 ...
- 编译时提示软件包 javax.servlet.http 不存在 import javax.servlet.http.HttpServletRequest;
编译时错误:软件包 javax.servlet.http 不存在import javax.servlet.http.HttpServletRequest; 解决办法:把servlet-api.jar加 ...
- servlet中使用request.getHeader("referer")获取页面从哪跳转过来的
问题 servlet中使用request.getHeader("referer")获取页面从哪跳转过来的,利用这个方法可以判断网页是否正常登录.我做了一个javaweb小项目,其中 ...
- JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...
- (转)JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...
- 在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 ...
- Servlet+Tomcat制作出第一个运行在Tomcat上的Java应用程序
转载自:http://www.linuxidc.com/Linux/2011-08/41685.htm [日期:2011-08-27] 来源:csdn 作者:Cloudyxuq 1.IDE工 ...
- 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法
Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...
- Servlet学习(二):ServletConfig获取参数;ServletContext应用:请求转发,参数获取,资源读取;类装载器读取文件
转载:http://www.cnblogs.com/xdp-gacl/p/3763559.html 一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件 ...
- Java-API:javax.servlet.http.HttpServletRequest
ylbtech-Java-API:javax.servlet.http.HttpServletRequest 1.返回顶部 1. javax.servlet.http Interface HttpSe ...
随机推荐
- delving into deep imbalanced regression翻译
非对照翻译,有所简略.翻译不对,尽情谅解,可留言 作者解释 and paper 笔记 Abstract Real-world data often exhibit imbalanced distr ...
- java匿名内部类的初解
java原生态中的匿名内部类 1.匿名内部类的定义 使用匿名内部类的两种的方法 建立父类,重写父类的方法 实现接口的方法 2.普通类的实现 1. 普通类实现 实现普通类需要先声明对一个类的对象,再调用 ...
- 【电脑Tips】Win11自动更新之后开机黑屏
目录 0.问题描述 1. 释放静电 具体操作 效果 参考博客 2. 运行explorer.exe 具体操作: [问题]:如何打开任务管理器? 效果 参考博客 另外的运行方法 3. 禁用APP Read ...
- React后台管理系统 02样式初始化,引入reset-css
上一篇中,我们已经对项目的整体结构进行了搭建,现在需要对不需要的东西进行删除,最后留下这些东西. 现在需要对全部的样式进行清除,使用命令导入依赖:npm i reset-css 然后在main.tsx ...
- Winform 巨好看的控件库推荐:MaterialSkin.2
MaterialSkin.2 控件包是在 MaterialSkin 及基础上二次开发而来的,在原控件基础上修复了一些Bug,丰富了主题以及动画效果,效果非常好. MaterialSkin.2 现在处于 ...
- python接口自动化封装导出excel方法和读写excel数据
一.首先需要思考,我们在页面导出excel,用python导出如何写入文件的 封装前需要确认python导出excel接口返回的是一个什么样的数据类型 如下:我们先看下不对返回结果做处理,直接接收数据 ...
- influxdb 中得 fields 与 tag 区别总结
本位为博主原创,转载请注明出处: 1.Field与Tag说明 在 InfluxDB 表结构中,field 和 tag 是用于存储数据的两种不同类型. Field(字段): Field 用于存储实际的数 ...
- H5 WebGL实现水波特效
前言 零几年刚开始玩电脑的时候,经常在安装程序上看到一种水波特效,鼠标划过去的时候,就像用手在水面划过一样,感觉特别有意思.但是后来,就慢慢很少见过这种特效了.最近突然又想起了这种特效,于是开始折磨怎 ...
- 即构✖叮咚课堂:行业第一套AI课堂解决方案是怎么被实现的?
AI走进教育,是传统教育的一次迭代进化 在教育问题上,我们看到两类话题最容易引发公众讨论:教育公平和个性化教育,"互联网+教育"有可能解决第一类话题,"AI教育" ...
- freeswitch的mod_cdr_csv模块
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 在语音呼叫的过程中,话单是重要的计价和结算依据,话单的产生需要稳定可靠,可回溯. fs中基本的话单模块mod_cdr_csv,可以满 ...