首页 > 其他分享 >[Servlet/Tomcat] HttpServletRequest#getHeader(headerNameWithIgnoreCase)(获取header时不区分大小写)

[Servlet/Tomcat] HttpServletRequest#getHeader(headerNameWithIgnoreCase)(获取header时不区分大小写)

时间:2023-09-16 19:33:04浏览次数:38  
标签:HttpServletRequest headerNameWithIgnoreCase http Tomcat getHeader request apache

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)

标签:HttpServletRequest,headerNameWithIgnoreCase,http,Tomcat,getHeader,request,apache
From: https://www.cnblogs.com/johnnyzen/p/17707173.html

相关文章

  • 关于Tomcat服务器
    Tomcat的启动和关闭:一般可以在下载文件下的bin目录中寻找startup.bar文件双击启动。手动关闭即可。本地web网页一般存放在webapps中,也可以在webapps中自定义页面关于配置文件一般存放在conf中的server.xml中,我么可以更改带端口号也可以自定义域名: 但这只是代表本地存在这......
  • Tomcat Filter 类型内存马与查杀学习(4)
    原理• 利⽤JavaAgent技术遍历所有已经加载到内存中的class先判断是否是内存⻢,是则进⼊内存查杀• 访问时抛异常(或跳过调⽤),中断此次调⽤• 从系统中移除该对象排查方式•如果是jsp注⼊⽇志中排查可疑jsp的访问请求• 如果是代码执⾏漏洞,排查中间件的er......
  • IDEA 22.2.3 创建web项目及Tomcat部署与服务器初始界面修改(保姆版)
    开始前请确认自己的Tomcat、JDK已经安装配置完毕不同版本的IDEA创建配置流程可能不同,演示中的IDEA版本号为22.2.3本教程创作时间为2023/09/141.创建项目通过下图路径进入创建界面,项目名称、路径、JDK都选择完毕后点击Create创建2.创建web目录右键单击目录名呼出二级菜单......
  • 更改Eclipse下Tomcat的部署目录和自定义user library
     更改Eclipse下Tomcat的部署目录http://kingxss.iteye.com/blog/1741438自定义userlibrary......
  • How to fix java.net.SocketException: Too many files open in tomcat
    NotmanyJavaprogrammersknowsthatsocketconnectionsaretreatedlikefilesandtheyusefiledescriptor,whichisalimitedresource.Differentoperatingsystemhasdifferentlimitsonnumberoffilehandlestheycanmanage.Oneof......
  • Tomcat的Session设置
    1、为单个WEB设置SESSION在WEB.XML中添加xml代码<session-config><session-timeout>15</session-timeout>//单位为分钟</session-config>2、为单个Servlet指定会话超时时间xml代码<servlet><servlet-name>Servlet名称</......
  • 同时启动多个Tomcat服务器
    前些时日,出于某种需要,需要同时启动多个Tomcat服务器,在网上查了半天,才找到解决的办法,拿出来分享一下,嘿嘿。我所用Tomcat服务器都为zip版,非安装版。以两个为例:安装第二个Tomcat完成后,到安装目录下的conf子目录中打开server.xml文件,查找以下三处:(1)修改http访问端口(默认为808......
  • 【Tomcat】【源码一】Tomcat 源码分析环境搭建
    1 前言ApacheTomcat®软件是JavaServlet、JavaServer页面、Java语言表达式和JavaWebSocket技术的开源实现。JavaServlet、JavaServer页面、Java表达式语言和JavaWebSocket规范都是在Java社区进程下开发的。ApacheTomcat软件是在开放和参与的环境中开发的,并在A......
  • tomcat报错:java.io.IOException: 您的主机中的软件中止了一个已建立的连接。页面响应
    tomcat报错:java.io.IOException:您的主机中的软件中止了一个已建立的连接。tomcat报错:org.apache.catalina.connector.ClientAbortException:java.io.IOException:您的主机中的软件中止了一个已建立的连接。 出现原因:1、由于客户端在发送请求后,还没等服务器响应就断开了......
  • windows环境下tomcat配置一些问题记录
    首先我们需要提前在电脑上安装jdk官网如下:JavaArchiveDownloads-JavaSE11|Oracle中国这里我安装的是jdk11 接着下载好tomcat安装包官网如下:ApacheTomcat®-Welcome!我下载的是9.0版本 复制安装路径配置环境变量对path进行修改 tomcat安装成功之后......