我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么给HttpServletRequest增加消息头

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么给HttpServletRequest增加消息头

小编给大家分享一下怎么给HttpServletRequest增加消息头,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

HttpServletRequest增加header

由于在请求中请求域的属性在请求转发,路由等过程中,请求域的值会丢失,在项目项目中使用请求头来传递信息,但是HttpRequest并没有实现增加请求头的方法,所以找到他的子类来实现

 class MutableHttpServletRequest extends HttpServletRequestWrapper {    // holds custom header and value mapping    private final Map<String, String> customHeaders;     public MutableHttpServletRequest(HttpServletRequest request){        super(request);        this.customHeaders = new HashMap<String, String>();    }        public void putHeader(String name, String value){        this.customHeaders.put(name, value);    }     public String getHeader(String name) {        // check the custom headers first        String headerValue = customHeaders.get(name);                if (headerValue != null){            return headerValue;        }        // else return from into the original wrapped object        return ((HttpServletRequest) getRequest()).getHeader(name);    }     public Enumeration<String> getHeaderNames() {        // create a set of the custom header names        Set<String> set = new HashSet<String>(customHeaders.keySet());                // now add the headers from the wrapped request object        @SuppressWarnings("unchecked")        Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();        while (e.hasMoreElements()) {            // add the names of the request headers into the list            String n = e.nextElement();            set.add(n);        }         // create an enumeration from the set and return        return Collections.enumeration(set);    }}

使用:

public class SecurityFilter implements javax.servlet.Filter {     @Override    public void destroy() {            }     @Override    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest req = (HttpServletRequest) request;        MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(req);        ...        mutableRequest.putHeader("x-custom-header", "custom value");        chain.doFilter(mutableRequest, response);    }     @Override    public void init(FilterConfig filterConfig) throws ServletException {            }}

但是项目中我使用的SpringCloud ZUUL中使用这样 的方式失败:

@Componentpublic class AccessFilter extends ZuulFilter {    private  Logger log = LoggerFactory.getLogger(AccessFilter.class);    @Autowired    private VerificationHelper helper;    private  BufferedReader reader=null;    @Autowired    private KeyAndFrequencyService service;    @Autowired    private ZuulTest zuulTest;    @Autowired    private PermissionHandler permissionHandler;    @Override    public String filterType() {        //前置过滤器        return "pre";    }    @Override    public int filterOrder() {        //优先级,数字越大,优先级越低        return 0;    }    @Override    public boolean shouldFilter() {        //是否执行该过滤器,true代表需要过滤        return true;    }    @Override    public Object run() {        RequestContext ctx = RequestContext.getCurrentContext();        HttpServletRequest request = ctx.getRequest();        try {            permissionHandler.setTokenExpireTime(200000000);            String type = request.getHeader("type");            zuulTest.say();            System.out.println("......................................................");            if (type == null) {                System.out.println("......................................................验证1");                Object object = helper.AccessZuul(request, ctx);                return object;            } else {                System.out.println("......................................................验证2");                PermissionResult result=permissionHandler.check(request);                System.out.println(result);                if(result.isState()){          MutableHttpServletRequest  mutRequest=new MutableHttpServletRequest (request);                     //增加头部信息                    DasAccountInfo accountInfo= permissionHandler.GetDasAccountInfoById(Integer.parseInt(result.getUserId()));                                        mutRequest.putHeader("dasAccountInfo", JSON.toJSONString(disablePropertyName()))                   ;RequestContext.getCurrentContext().setRequest(mutRequest);                    ctx.setSendZuulResponse(true);// 对该请求进行路由                    ctx.setResponseStatusCode(200);                    ctx.set("isSuccess", true);                }else{                    ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由                    ctx.setResponseStatusCode(401);// 返回错误码                    ctx.setResponseBody("{\"code\":0,\"result\":\"网关验证失败!验证方式为2\"}");// 返回错误内容                    ctx.set("isSuccess", false);                }            }        }catch (Exception e){            e.printStackTrace();            log.error("网关报错!!!",e.fillInStackTrace());        }           return null;    }

使用zuul网关的自带的设置请求头的方法,在网关中设置的请求头可以被路由下面的服务获取到:

ctx.getZuulRequestHeaders().put("dasAccountInfo", JSON.toJSONString(disablePropertyName()));

修改HttpServletRequest中header的信息

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

总结一句,我就是想想header中加东西!!往下看具体实现方式:

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

@Overridepublic 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);}

说明:可以看到在方法中,

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

gsid= request.getParameter("GSID");

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

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

解释:

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

怎么给HttpServletRequest增加消息头

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

怎么给HttpServletRequest增加消息头

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

这个类中找getHeader方法

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

找到这个类中的coyoteRequest

protected org.apache.coyote.Request coyoteRequest;

是这样的

怎么给HttpServletRequest增加消息头

再找到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对象

怎么给HttpServletRequest增加消息头

这里有name,value,靠谱

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

测试请求:

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

测试打印结果:

怎么给HttpServletRequest增加消息头怎么给HttpServletRequest增加消息头

以上是“怎么给HttpServletRequest增加消息头”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么给HttpServletRequest增加消息头

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么给HttpServletRequest增加消息头

小编给大家分享一下怎么给HttpServletRequest增加消息头,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!HttpServletRequest增加hea
2023-06-20

php怎么给json增加值

php给json增加值的方法:1、使用json_decode()函数将json数据转为数组类型,语法“json_decode(json数据,TRUE)”;2、使用“$数组变量名[新键名]=新值;”语句在数组的末尾增加新值;3、使用json_encode()函数将增加值后的数组转回JSON类型即可,语法“json_encode(数组)”。本教程操作环境:windows7系统、PHP8.1版、DELL
2022-06-14

怎么给numpy.array增加维度

怎么给numpy.array增加维度?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。输入:import numpy as np a = np.array([1, 2, 3])pr
2023-06-15

mysql怎么给表增加主键

在MySQL中,可以使用ALTER TABLE语句来给表增加主键。以下是一个示例:ALTER TABLE table_nameADD PRIMARY KEY (column_name);在上面的示例中,你需要将table_name替换为
mysql怎么给表增加主键
2024-04-09

php怎么给数组增加数据

php给数组增加数据的方法:1、使用“array_unshift(数组,数据值1,数据值2...)”语句;2、使用“array_push(数组,值1,值2...)”语句;3、使用“array_splice(数组,开始位置,0,值)”语句。
2015-02-22

怎么给linux增加磁盘容量

要给Linux增加磁盘容量,可以执行以下步骤:1. 打开终端窗口,以root用户或具有管理员权限的用户身份登录。2. 使用命令`fdisk -l`查看当前系统的磁盘分区情况,找到需要扩展的磁盘。3. 使用`fdisk /dev/sdX`(X
2023-10-12

php怎么实现响应头增加token

php实现响应头增加token的方法:1、在请求的header头中的Authorization字段使用Bearer模式添加JWT;2、在服务器收到请求后,使用JWT规范,进行生成token,返回给客户端即可。
2023-05-14

mfc怎么添加消息映射

要在MFC中添加消息映射,可以按照以下步骤进行操作:打开MFC应用程序的资源视图。双击资源视图中的对话框或窗口,打开对话框或窗口的类视图。在类视图中,右键单击对话框或窗口的类名,选择“Add Message Handler”(添加消息处
2023-10-21

php怎么给指定日期增加天数

增加方法:1、使用“strtotime('日期-月份-天数')”语句将指定日期转为时间戳;2、将需要添加的天数转为秒数值,语法“天数 *24 * 3600”;3、使用“date('Y-m-d',时间戳+秒数值)”语句给日期增加指定天数。
2019-03-22

php中怎么给数组增加一个字段

php中给数组增加一个字段的方法:1、定义一个键值对形式的数组;2、直接通过“$array_test['new_test'] = $new_test;”方式增加一个字段即可。
2019-11-05

Java中怎么给图片增加倒影效果

本篇文章为大家展示了Java中怎么给图片增加倒影效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。实现原理倒影率作为参数rate 传入Reflection button的事件处理函数:CreateI
2023-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录