`
vinson00
  • 浏览: 20338 次
文章分类
社区版块
存档分类
最新评论

修改request中header的值

阅读更多

      在java web开发中,我们有时候会遇到需要修改request中请求值的问题,虽然这个不是特别常见。初看这是一个简单的问题,因为我们能通过HttpServletRequest对象拿到我们需要的所有关于当前这个请求的所有信息,想当然的也就可以修改所以这些信息。可实际情况是HttpServletReques中很多的属性只有getter方法,而没有setter方法,也就是说我们不可以修改他们。

        记得第一次遇到这种问题还是初学编程的时候,最近又遇到这个问题,就记录一下。最近遇到的是在spring mvc中,使用@RequestBody注解把requestBody中的json映射到java的object。我们知道对于spring mvc来说,这样使用的时候需要在请求的header里面表明conten-type为application/json。如果完全是自己开发的系统,没有问题加上就是,但是当和第三方合作的时候,请求的发起方式就不是我们能控制住的了。现在的问题是如果使用spring mvc的这种开发模式,必须要在请求的header中设置content-type为application/json,但是第三方又不方便设置。所以只能在所有针对第三方的API中进行特殊处理。

       sping mvc是基于servlet的,我们只要在请求进入servlet之前在header中设置content-type为application/json就ok了,所以理想的修改方式就是加入一个filter。现在就到了关键的问题:怎么修改请求的header值。答案是利用HttpServletRequestWrapper类。

 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new CustomeizedRequest((HttpServletRequest) request), response);
    }

    private class CustomeizedRequest extends HttpServletRequestWrapper {

        public CustomeizedRequest(HttpServletRequest request) {
            super(request);
        }

        @Override
        public Enumeration<String> getHeaders(String name) {
            if (null != name && name.equals("Content-Type")) {
                return new Enumeration<String>() {
                    private boolean hasGetted = false;

                    @Override
                    public String nextElement() {
                        if (hasGetted) {
                            throw new NoSuchElementException();
                        } else {
                            hasGetted = true;
                            return "application/json;charset=utf-8";
                        }
                    }

                    @Override
                    public boolean hasMoreElements() {
                        return !hasGetted;
                    }
                };
            }
            return super.getHeaders(name);
        }
    }

 

       demo中只重写了getHeaders方法,实际上严谨的做法是getHeader(String name)方法也要被重写。实质上我们还是没有改变header中的值的能力,但是我们重写了getHeaders方法,当发现是我们的Content-Type字段时,只要返回我们想要设置的值就OK了。同理我们可以任意发挥,根据实际的情况去重写相应的方法。

      说一下我在这里遇到的一个问题,在开发过程中使用的maven加jetty插件,运行起来没有问题。但是测试和生产环境用的是tomcat,上了测试环境发现没有效果。第一感觉是不同的容器中Content-Type的大小写或写法不一样。打了一个log继续测试,发现tomcat好像根本没进入我的getHeaders方法,就开始怀疑tomcat和jetty的某些实现不一致,各种查找没有结果。最后在本地换成tomcat来debug,竟然进入了重写的getHeaders方法,再一看name的值是:content-type。粗心把log打错位置了。。。,刚开始猜想的是对的。

       所以这里的name.equals("Content-Type")就要考虑大小写和不同写法的因素了(比如contenttype或ContentType)。

后来想了一下之所以会出现这个失误有两个原因:

  1.  粗心 log打错位置
  2.  自身对于容器不熟悉,而且之前遇到过tomcat和jetty对于某些请求作不同处理的情况,所以就找错了方向。
分享到:
评论

相关推荐

    教你怎么用Nginx往request的header中添加新字段

    结合提供的文件名,我们可以推断,`2nginx response.png`可能展示了Nginx添加自定义响应头的结果,`1request header中添加apiversion.png`可能描绘了在请求头中添加`apiversion`字段的过程,而`Nginx居然还能实现...

    request的使用.txt

    在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、...

    Header Editor

    2. **修改请求头**:在开发过程中,可能需要临时改变某些请求头的值以测试不同的场景,例如修改"Accept"头来测试不同格式的响应,或者改变"User-Agent"以模拟不同设备或浏览器的行为。 3. **删除请求头**:有些情况...

    ajax 缓存 问题 requestheader

    2. `If-Modified-Since`: 这个头字段包含了一个日期/时间值,表示客户端已经拥有的资源的最后修改时间。如果服务器上的资源自那时起没有改变,服务器可以返回一个304 Not Modified状态码,告知浏览器使用本地缓存的...

    java httpClient status 400错误的Header中字符不合法(csdn)————程序.pdf

    RequestInterceptor是Feign的一个特性,允许我们在请求发送之前修改或添加Header。在这个案例中,Interceptor在Header中添加了一个中文值,而这可能违反了HTTP规范,因为HTTP Header通常只接受ASCII字符。 进一步...

    详解Retrofit Interceptor(拦截器) 拦截请求并做相关处理

    在 intercept 方法中,我们首先获取 Request 对象,然后添加统一参数或修改 header,最后调用 chain.proceed() 方法来继续执行请求。 在使用 Interceptor 时,我们需要将其添加到 Retrofit 客户端中。下面是一个...

    Request&Response对象主要方法

    - **功能**:设置或修改响应头中的某个字段。 - **参数**:`name` - 响应头字段的名称;`value` - 字段的值。 - **返回值**:无。 以上方法是`HttpServletRequest`和`HttpServletResponse`中最常用的部分,它们为...

    tcp/ip-HTTP-Header-消息报头

    通用首部字段是既可以出现在请求消息也可以出现在响应消息中的首部字段,主要包括以下几种: - **Cache-Control**: 控制缓存行为,如`no-cache`、`no-store`等。 - **Connection**: 指示连接是否保持打开状态,例如...

    Modify Header Value (HTTP Headers)-crx插件

    修改标题值(HTTP标头)是可以添加,修改或删除HTTP-Request-Header的扩展名对于所需网站或URL上的所有请求。如果您是App Developer,网站设计师,或者您想在网站上的请求中测试特定标题,则此插件非常有用。主要...

    RequestConnControl.rar_The Request

    拦截器修改了原始请求,添加了一个"Connection"头部,值设为"Keep-Alive"。这样,当服务器收到这个请求时,就会知道客户端希望保持连接开放。 在实际应用中,我们需要将这个拦截器添加到 OkHttpClient 的拦截器链中...

    Spring拦截器,高级参数绑定

    例如,可以使用`@RequestParam`、`@PathVariable`、`@RequestHeader`、`@RequestBody`等注解来实现不同类型的参数绑定: ```java @PostMapping("/example") public String example(@RequestParam("name") String ...

    HTTP_Header_详解.doc

    HTTP Header 是超文本传输协议(HTTP)中极为关键的一部分,用于在客户端(如浏览器)和服务器之间传递附加信息,这些信息包括请求的细节、响应的状态以及关于数据内容的元信息。HTTP Header 可以帮助优化通信效率,...

    Django接收自定义http header过程详解

    在WSGIRequestHandler类的get_environ方法中,会首先从服务器的基础环境信息中复制一份,并添加或修改其中的一些键值对来适应当前的HTTP请求。例如,会将SERVER_PROTOCOL设置为请求的HTTP版本,REQUEST_METHOD设置为...

    详解okhttp3 请求头不能为中文的坑

    如果请求头的键或值中包含ASCII字符集(范围0x0020-0x007F)之外的字符,就会抛出IllegalArgumentException异常。由于中文字符的编码范围超出了ASCII字符集,因此不能直接使用中文作为请求头的键或值。 这个检查是...

    php中XMLHttpRequest(Ajax)不能设置自定义的Referer的解决方法

    在本例中,Referer 值中的中文字符使用了 URL 编码。 4. 维护性:考虑到维护和可能的服务器配置更改,需要确保代码在未来的运行环境中保持可用性。 总的来说,使用 PHP cURL 库绕过 XMLHttpRequest 的限制来设置...

    go语言在请求http时加入自定义http header的方法

    使用Add方法,我们可以向特定的HTTP头中添加值。例如,如果我们想设置User-Agent头,可以像下面这样操作: ```go req.Header.Add("User-Agent", "myClient") ``` 上述代码展示了如何创建一个POST类型的HTTP请求,...

    JSP 中request与response的用法详解

    - 设置响应头:通过setHeader(String name, String value)方法可以添加或修改响应头。 - 发送重定向:通过sendRedirect(String location)方法可以重定向客户端到另一个URL。 - 输出内容到客户端:通过getWriter()...

    最新ajax常用的函数大全

    // 如果服务器响应的header不是text/xml,可以调用其他方法修改header http_request.overrideMimeType('text/xml'); } } else if (window.ActiveXObject) { // 对于 Internet Explorer 浏览器 try { ...

    miniui demo

    开发者可以通过查看和修改这些示例,了解如何在自己的项目中使用 MiniUI。HTML 文件中通常会引用 MiniUI 的 JavaScript 和 CSS 文件,并通过 JavaScript 代码来初始化和操作 MiniUI 组件。例如,创建一个表格可能...

    springboot使用filter获取自定义请求头的实现代码

    Filter 可以实现过滤请求和响应的数据,例如,检查和修改请求 headers、cookies、响应内容等。 知识点二:Spring Boot 中的 Filter 在 Spring Boot 中,Filter 可以通过实现 Filter 接口来创建。例如,下面是一个...

Global site tag (gtag.js) - Google Analytics