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时不区分大小写)的更多相关文章

  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. ImageMagick 图像处理学习笔记

    Use ImageMagick to create, edit, compose, or convert bitmap images. It can read and write images in ...

  2. 五年磨一剑——Sealos 云操作系统正式发布!

    这是个宏伟的计划 这是一个宏伟的计划,漫长且有趣. 2018 年的某个夜晚,夜深人静,我挥舞键盘,敲下了 Sealos 的第一行代码.当时仓库命名为 "kubeinit",后来觉得 ...

  3. 基于html2canva jspdf 实现前端页面加水印 并导出页面PDF

    基于html2canva jspdf 实现前端页面加水印 并导出页面PDF; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12 ...

  4. ASIC加速技术在ASIC加速性能优化中的新应用与挑战

    目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 5. 优化与改进 1. 引言 随着计算机技术的发展,芯片的性能和面积都得到了极大的提升.为了进一步提高芯片的 ...

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

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

  6. 驱动开发:摘除InlineHook内核钩子

    在笔者上一篇文章<驱动开发:内核层InlineHook挂钩函数>中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能 ...

  7. 基于Surprise协同过滤实现短视频推荐

    ​ 前言 前面一文介绍了通过基础的web项目结构实现简单的内容推荐,与其说那个是推荐不如说是一个排序算法.因为热度计算方式虽然解决了内容的时效质量动态化.但是相对用户而言,大家看到的都是几乎一致的内容 ...

  8. [SDOI2008] 仪仗队【题解】

    题目描述 作为体育委员,C 君负责这次运动会仪仗队的训练.仪仗队是由学生组成的 \(N \times N\) 的方阵,为了保证队伍在行进中整齐划一,C 君会跟在仪仗队的左后方,根据其视线所及的学生人数 ...

  9. Oracle分组取最大值

    需求 该SQL是一个子SQL,需要查询出某个人所有过往履历中职务最高的 SELECT a."EMP_ID",a."CADRE_LEVEL" FROM (SELE ...

  10. 2021-7-12 VUE的过滤器使用

    过滤器实例:转换首字母大写 <!DOCTYPE html> <html> <head> <title> </title> </head ...