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. 【Python入门教程】Python常用表格函数&操作(xlrd、xlwt、openpyxl、xlwings)

    ​         在我们使用Python时,避免不了与Excel打交道.同样Python的三方库和代码的简洁性也为我们处理大数据提供了便利.今天给大家介绍一下常用的处理表格的函数,同时还有一些常用的 ...

  2. Python潮流周刊#7:我讨厌用 asyncio

    你好,我是猫哥.这里记录每周值得分享的 Python 及通用技术内容,部分为英文,已在小标题注明.(标题取自其中一则分享,不代表全部内容都是该主题,特此声明.) 首发于我的博客:https://pyt ...

  3. 【tvm解析】 Operator Strategy 机制

    本文地址:https://www.cnblogs.com/wanger-sjtu/p/15082871.html Relay Operator Strategy是建立Relay IR与TOPI算子库的 ...

  4. C++面试八股文:override和finial关键字有什么作用?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第22面: (二师兄好苦逼,节假日还在面试...) 面试官:C++的继承了解吗? 二师兄:(不好意思,你面到我的强项了..)了解一些. 面试官:什么是 ...

  5. LLM技术在自然语言处理中的实践与改进

    目录 <LLM技术在自然语言处理中的实践与改进> 引言 自然语言处理 (NLP) 是人工智能领域的一个重要分支,它研究如何将计算机程序与人类语言进行交互,从而理解.分析.生成和翻译文本.近 ...

  6. typescript的必要性及使用

    1 前言 作为一个前端语言,Javascript从最初只是用来写页面,到如今的移动终端.后端服务.神经网络等等,它变得几乎无处不在.如此广阔的应用领域,对语言的安全性.健壮性以及可维护性都有了更高的要 ...

  7. Mininet教程

    mininet的安装 1.前言 1.本次安装环境为ubuntu20.04. 2.mininet 为 github上的最新版,我已经修改镜像地址并克隆到了gitee,只需要从我的gitee仓库克隆即可. ...

  8. Python 一大坑,配置文件中字典引用问题(拷贝)。

    大坑 +1 python 配置文件中字典引用问题 最近在开发系统时发现一个传奇的BUG, 用户未登录就可进入系统内,而且含有真实身份信息. 此问题困扰多时,反复debug.由于找不到问题原因,复现具有 ...

  9. HCL实验:1.两台PC通过交换机ping通

    实验整体的拓扑图 进行交换机配置 配置好PC的ip netmask gatework 接口管理为启用状态 开启SW1 连接的端口 (一般来说是默认打开的,但有时候会自动关闭,很烦,所以最好加上这步) ...

  10. 分别在Windows系统和Linux系统环境安装anaconda3和tensorflow

    Windows系统环境 一.安装anaconda 这里安装的是Anaconda3-2019.03-Windows-x86_64.exe(python3.7版本) 二.检查安装环境 1.若anacond ...