[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 ...
随机推荐
- 20200411 联想Yoga 2 13升级大SSD
20200411:下文的操作实际发生在2018年11月,当时完成了就写好了这篇文章,却忘了放上来,最近家里一个电脑的硬盘坏了,来翻箱底才找到,现在发上来. 原配置:Lonevo Yoga2 13,唯一 ...
- go语言字符与字符串相关
ASCII ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁 字母的一套单字节编码系统 字符 本质上来 ...
- VS2017登录账户提示升级Edge浏览器的问题
在win7系统登录VS2017账号总是提示要升级浏览器的问题,这里给大家提供一个解决办法,也是困扰我很久的问题.遇到这中问题,我们可以在VS工具->选项->账户,然后勾选在添加账户或对账户 ...
- 这问题巧了,SpringMVC 不同参数处理机制引发的思考
这个问题非常有趣,不是SpringMVC 的问题,是实际开发中混合使用了两种请求方式暴露出来的. 问题场景 功能模块中,提供两个 Http 服务.一个是列表查询(application/json 请求 ...
- WebAPI公开接口请求签名验证
前言 现在的系统后端开发的时候,会公开很多API接口 对于要登录认证后才能访问的接口,这样的请求验证就由身份认证模块完成 但是也有些接口是对外公开的,没有身份认证的接口 我们怎么保证接口的请求是合法的 ...
- 聊聊JVM虚方法表和方法调用
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.源码解析.科技故事.项目实战.面试八股等更多硬核文章,首发于公众号「小牛呼噜噜」 大家好,我是呼噜噜,好久没更新文 ...
- 推荐一款C#开源的操作简单、免费的屏幕录制和GIF动画制作神器
前言 今天要给大家推荐一款由C#语言开发且开源的操作简单.免费的屏幕录制和GIF动画制作神器:ScreenToGif . 工具介绍 ScreenToGif 是一款免费的开源屏幕录制和GIF 制作工具. ...
- 配置http协议访问Harbor镜像仓库
解决http: server gave HTTP response to HTTPS client问题,此问题在上传与下载时均可能出现. 由于docker镜像拉取与推送服务使用的是https协议,但是 ...
- 我和ChatGPT聊数字人
近期,聊天机器人ChatGPT火了,写诗写文写代码,才艺狠狠拉满. 面对如此"会聊"的ChatGPT,很多人好奇相同的问题提问ChatGPT和真人,会有什么样的结果? 于是我们 ...
- WebSSH远程管理Linux服务器、Web终端窗口自适应(二)
上一篇:Gin+Xterm.js实现WebSSH远程Kubernetes Pod 支持用户名密码认证 支持SSH密钥认证 支持Web终端窗口自适应 支持录屏审计 Go SSH golang.org/x ...