如何修改HttpServletRequest中header中的信息

目录
  • 总结一句话
  • 往下看具体实现方式
  • 说明:可以看到在方法中
    • 解释
    • 具体过程如下

废话一堆:

由于业务有统一的鉴权系统,页面请求时在header中带过来gsid,正常业务没有问题,但是当需要下载文件时,前端统一用json解析响应,当响应文件时,对于前端来说不好处理,就决定使用简单的get请求下载文件,将gsid通过url带过来,这样的话后端鉴权就需要处理,当header中没有gsid时,从参数中取,为了尽可能少的改变公用的业务代码(指sso),就在当前项目中自定义权限拦截器。

总结一句话

我就是想想header中加东西!!

往下看具体实现方式

新建拦截器类,继承原有的拦截器,重写其preHandle方法

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
    String gsid = request.getHeader("GSID");
    if(StringUtils.isBlank(gsid)){
        String gsid= request.getParameter("GSID");
        //使用反射,将gsid设置到request中的的header中去
        reflectSetparam(request,"GSID",gsid);
        log.info("请求连接中的gsid={}",request.getHeader("GSID"));
    }
    return super.preHandle(request, response, o);
}

说明:可以看到在方法中

1、先进行header信息判断,如果header中没有GSID,就去请求参数中拿

gsid= request.getParameter("GSID");

2、通过反射将参数中的GSID键值对儿:“GSID”:“376645354562335”加入到header中去

话不多少,先上代码,再解释:

解释

/**
 * 修改header信息,key-value键值对儿加入到header中
 * @param request
 * @param key
 * @param value
 */
private void reflectSetparam(HttpServletRequest request,String key,String value){
    Class<? extends HttpServletRequest> requestClass = request.getClass();
    System.out.println("request实现类="+requestClass.getName());
    try {
        Field request1 = requestClass.getDeclaredField("request");
        request1.setAccessible(true);
        Object o = request1.get(request);
        Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
        coyoteRequest.setAccessible(true);
        Object o1 = coyoteRequest.get(o);
        System.out.println("coyoteRequest实现类="+o1.getClass().getName());
        Field headers = o1.getClass().getDeclaredField("headers");
        headers.setAccessible(true);
        MimeHeaders o2 = (MimeHeaders)headers.get(o1);
        o2.addValue(key).setString(value);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

执行打印信息如下:

request实现类=org.apache.catalina.connector.RequestFacade
    coyoteRequest实现类=org.apache.coyote.Request

看HttpServletRequest的源码,是个接口,并且我们获取header信息的方法是getHeader()方法,按常理其对象中应该有header字段,那么我们就去实现类中找这个字段

具体过程如下

步骤一:先找到具体的Request对象是哪个类,根据打印信息看源码

进入其中找到getHeader()方法,如下

public String getHeader(String name) {
    if (this.request == null) {
        throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
    } else {
        return this.request.getHeader(name);
    }
}

然后我们找this.request

这个request,我们找到它的类型,点击去

这个类的全路径是:org.apache.catalina.connector.Request

这个类中找getHeader方法

public String getHeader(String name) {
    return this.coyoteRequest.getHeader(name);
}

找到这个类中的coyoteRequest

protected org.apache.coyote.Request coyoteRequest;

是这样的

再找到getHeader()

public String getHeader(String name) {
    return this.headers.getHeader(name);
}

好了,终于见到属性了

private final MimeHeaders headers = new MimeHeaders();

找到MineHeaders中的getHeader方法,

public String getHeader(String name) {
    MessageBytes mh = this.getValue(name);
    return mh != null ? mh.toString() : null;
}

看到最终header是一个MessageBytes对象,好找到这个对象进去,发现只能setValue,那就在MineHeaders中找在哪里实例化MessageBytes对象的

找了半天找到在createHeader()方法中实例化MimeHeaderField对象,然后这个对象实例化时会实例化MessageBytes对象

这里有name,value,靠谱

然后再在MimeHeader中找在addValue方法中有调用,就用这个试一下吧,然后就是最上面的我自定义的方法,在heade中加入了一个键值对儿。

测试请求:

http://127.0.0.1:32100/v1/CustomerRefundRest/exportRefund?gsid=abc114f1bd0d484084e5df3fe1c419b8&refundLongStartDate=1520611199000&refundLongEndDate=1522943999000

测试打印结果:

OVER!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用SpringMVC 重写、扩展HttpServletRequest请求参数

    一.背景说明 由于在项目进行前后端分离改造时,请求由多种传参方式统一定义为JSON格式传输,在改造过程中需要前后版本兼容.如果能在Controller接收参数之前将JSON格式参数进行解析成原有参数,对Request请求参数进行重写,这样能可以大大减少开发成本. 二.调研 抱着对Request请求参数目标出发,对@InitBinder和HttpServletRequestWrapper进行了研究,最终使用HttpServletRequestWrapper解决了当前问题. 1.@InitBinde

  • java 获取HttpRequest Header的几种方法(必看篇)

    在开发应用程序的过程中,如果有多个应用,通常会通过一个portal 门户来集成,这个portal  是所有应用程序的入口,用户一旦在portal 登录之后,进入另外一个系统,就需要类似的单点登录(SSO). 进入各个子系统的时候,就不需要再次登录, 当然类似的功能,你可以通过专业的单点登录软件来实现,也可以自己写数据库token 等方式来实现.其实还有一个比较简单的方法,就是通过 portal 封装已经登录过的用户的消息,写到http header 之中,然后把请求forward 到各个子系统中

  • HttpServletRequest对象方法的用法小结

    深入体验JavaWeb开发内幕--关于HttpServletRequestRequest对象 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的相关方法,即可以获得客户的这些信息. 一.通过request常用方法获得相关信息: 1.通过request常用方法获得客户机信息 getRequestURL方法返回客户端发出请求时的完整URL. getRequestURI方法返回请求行中的资

  • 如何修改HttpServletRequest中header中的信息

    目录 总结一句话 往下看具体实现方式 说明:可以看到在方法中 解释 具体过程如下 废话一堆: 由于业务有统一的鉴权系统,页面请求时在header中带过来gsid,正常业务没有问题,但是当需要下载文件时,前端统一用json解析响应,当响应文件时,对于前端来说不好处理,就决定使用简单的get请求下载文件,将gsid通过url带过来,这样的话后端鉴权就需要处理,当header中没有gsid时,从参数中取,为了尽可能少的改变公用的业务代码(指sso),就在当前项目中自定义权限拦截器. 总结一句话 我就是

  • HTTP中header头部信息详解

    HTTP Request的Header信息 1.HTTP请求方式 如下表: GET 向Web服务器请求一个文件 POST 向Web服务器发送数据让Web服务器进行处理 PUT 向Web服务器发送数据并存储在Web服务器内部 HEAD 检查一个对象是否存在 DELETE 从Web服务器上删除一个文件 CONNECT 对通道提供支持 TRACE 跟踪到服务器的路径 OPTIONS 查询Web服务器的性能 说明: 主要使用到"GET"和"POST". 实例: POST /

  • jQuery在header中设置请求信息的方法

    jquery是js的类库,js本身不能操作header,因为js是在浏览器加载页面过程中才开始执行的header需要服务器端执行操作 如果是ajax,是可以设置header $.ajax({ url: "", data: {}, type: "GET", beforeSend: function(xhr){xhr.setRequestHeader('X-Test-Header', 'test-value');},//这里设置header success: funct

  • 探讨php中header的用法详解

     header() is used to send raw HTTP headers. See the HTTP/1.1 specification for more information on HTTP headers. 范例一: 复制代码 代码如下: <?PHPHeader("Location: http://www.jb51.net";); exit;//在每个重定向之后都必须加上"exit",避免发生错误后,继续执行.?> 复制代码 代码如下:

  • PHP中Header使用的HTTP协议及常用方法小结

    本文实例总结了PHP中Header使用的HTTP协议及常用方法.分享给大家供大家参考.具体方法如下: 复制代码 代码如下: <?PHP function https($num) { $http = array ( 100 => "HTTP/1.1 100 Continue", 101 => "HTTP/1.1 101 Switching Protocols", 200 => "HTTP/1.1 200 OK", 201 =

  • PHP中读取照片exif信息的方法

    先来了解什么是图片的Exif信息 Exif是一种图象文件格式,它的数据存储与JPEG格式是完全相同的.实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈.快门.白平衡.ISO.焦距.日期时间等各种和拍摄条件以及相机品牌.型号.色彩编码.拍摄时录制的声音以及全球定位系统(GPS).缩略图等.简单地说,Exif=JPEG+拍摄参数.因此,你可以利用任何可以查看JPEG文件的看图软件浏览Exif格式的照片,但并不是所有的图形程序都能处理Exif信息. 以上引自百度百科. 读

  • 微信小程序如何修改本地缓存key中单个数据的详解

    最近在做教师评教系统,有一个'个人信息'页面中有个编辑修改邮箱的功能,本来想得很简单,结果进坑了,搞了好久才出来. 我想实现的效果是点击下图左侧邮箱,然后进入右侧页面,进行邮箱的修改,点击提交后跳转到左侧页面,同时邮箱也发生改变. 点击'我的'时,我让它从控制台打印出student缓存中传过来的数据,如下: {no: "1635050601", name: "张三", sex: "", email: "123@qq.com",

  • asp.net 合并GridView中某列相同信息的行(单元格)

                                            解决方法如下(写在公共模块里,定义为静态方法方便调用): 复制代码 代码如下: /// <summary> /// 合并GridView中某列相同信息的行(单元格) /// </summary> /// <param name="GridView1">GridView</param> /// <param name="cellNum"

  • PHP中header用法小结

    本文实例总结了PHP中header用法.分享给大家供大家参考,具体如下: PHP 中 header()函数的作用是给客户端发送头信息. 什么是头信息? 这里只作简单解释,详细的自己看http协议. 在 HTTP协议中,服务器端的回答(response)内容包括两部分:头信息(header) 和 体内容,这里的头信息不是HTML中的<head></head>部分,同样,体内容也不是<BODY>< /BODY>.头信息是用户看不见的,里面包含了很多项,包括:服务

  • SpringMVC中RequestContextHolder获取请求信息的方法

    RequestContextHolder的作用是: 在Service层获取获取request和response信息 代码示例: ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attrs.getRequest(); 源码分析: 定义了两个ThreadLocal变量用来存储Reque

随机推荐