【问题标题】:HttpResponse headers in Servlet or Filter or ListenerServlet 或 Filter 或 Listener 中的 HttpResponse 标头
【发布时间】:2017-03-04 12:58:17
【问题描述】:

我们如何在 HttpServletResponse 中获取 HTTP 响应标头,例如 Content-Type、Server 等?需要获取所有可用的此类标头。

当我们使用 UrlConnection 的 openConnection 并使用 getHeaderFields 时,我们会得到所有此类标头。但是当我们将 getHeaderNames 与 HttpServletResponse 一起使用时,我们不会得到这样的标头。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{

    Enumeration<String> requestHeaders = request.getHeaderNames();
    while(requestHeaders.hasMoreElements())
    {

        String header = requestHeaders.nextElement();
        System.out.println("request headerrrrrrr>>" + header);
    }

    Collection<String> responseHeaders = response.getHeaderNames();
    Iterator<String> it = responseHeaders.iterator();
    while(it.hasNext()){
        String header = it.next();
        System.out.println("response headerrrrrr>>" + header);
    }

    response.getWriter().append("Served at: ").append(request.getContextPath());
}

在 chrome 开发者工具中,我可以看到以下内容

General

Request URL:http://localhost:8080/TestWebApp/MyTestServlet
Request Method:GET
Status Code:200 OK
Remote Address:[::1]:8080

Response Headers

Content-Length:22
Date:Fri, 03 Mar 2017 07:40:56 GMT
Server:Apache-Coyote/1.1

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:JSESSIONID=DF62FC092F67FBB02AF68BC646085065; ai_user=MKfG+|2017-03-02T10:44:54.721Z; _ga=GA1.1.1362801303.1488451499
Host:localhost:8080
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

但控制台输出只是请求标头

request headerrrrrrr>>host
request headerrrrrrr>>connection
request headerrrrrrr>>upgrade-insecure-requests
request headerrrrrrr>>user-agent
request headerrrrrrr>>accept
request headerrrrrrr>>accept-encoding
request headerrrrrrr>>accept-language
request headerrrrrrr>>cookie

我按照 Log only http servlet response headers 的 BalusC 回答中提到的那样做了。但似乎没有像我需要的那样工作

使用 doFilter 方法创建一个过滤器,如下所示

public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {

    DOMConfigurator.configure("C:\\log4j.xml");

    Logger logger = Logger.getLogger(TestFilter.class);
    logger.info("do Filter TestFilter");
    final Map<String, List<String>> headers = new HashMap<String, List<String>>();

    chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
        @Override public void setHeader(String name, String value) {
            List<String> values = new ArrayList<String>();
            values.add(value);
            headers.put(name, values);
            super.setHeader(name, value);
        }

        @Override public void addHeader(String name, String value) {
            List<String> values = headers.get(name);
            if (values == null) {
            values = new ArrayList<String>(); 
            headers.put(name, values);
            }
            values.add(value);
            super.addHeader(name, value);
        }
    });

    logger.info("headers size>>"+headers.size());
    logger.info("these are the headers>>"+headers);

}

控制台日志是

INFO    2017-03-03 05:14:23,765 [http-bio-8080-exec-3] com.test.TestFilter  - do Filter TestFilter
INFO    2017-03-03 05:14:23,768 [http-bio-8080-exec-3] com.test.TestFilter  - headers size>>0
INFO    2017-03-03 05:14:23,768 [http-bio-8080-exec-3] com.test.TestFilter  - these are the headers>>{}

也许我确实错过了什么?

【问题讨论】:

  • 你想达到什么目的?响应用于将内容写入浏览器。所以你应该用它来set headers。不要阅读它们。
  • 当我们调用 servlet 时,我们会得到响应和响应标头。这个响应标头正在浏览器中打印。那么,相同的响应头,我们可以在 servlet 或过滤器中获取它吗?就像我们将这些标头作为 UrlConnection.getHeaderFields 的一部分获取的方式一样

标签: java servlets jakarta-ee servlet-filters


【解决方案1】:

正如在 cmets 中所说,servlet 负责在每个 http 请求的响应中生成标头。

标头主要用于创建客户端和服务器之间的对话。


GET 示例

client:给我/ MyTestServlet 对象,我希望它是一个html 页面。如果它被压缩它会更好,但如果不是它也很好。

Accept: text/html,application/xhtml+xml
Accept-Encoding: gzip, deflate

服务器:好的,我正在发送一个字符集 iso-8859-1 的 html,抱歉,它没有按您的要求压缩,长度为 9639 字节,最后一次修改是在 2 月 13 日 BTW ,我是“MySuperServer”。

Content-Type: text/html
Content-Length: 9639
Last-Modified: Mon, 13 Feb 2017 12:47:56 GMT
Server: MySuperServer

这个 GET 的代码是:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    String contentType = request.getHeader("Accept");
    if (contentType.contains("text/html") || contentType.contains("*/*")) {
        // the client expects for a web page (or anything), so let's send it
        String page = createSomehowPage();
        response.addHeader("Content-Type", "text/html");
        response.addHeader("Content-Length", String.valueOf(page.length()));
        response.addHeader("Last-Modified", "Mon, 13 Feb 2017 14:42:56 GMT");
        response.addHeader("Server", "MySuperServer");
        response.getWriter().append(page);
        response.setStatus(200);
    } else {
        response.addHeader("Server", "MySuperServer");
        response.getWriter().append("Sorry, I don't serve the content-Type '").append(contentType).append("' you asked");
        response.setStatus(406); // 406=Not Acceptable
    }
}

您可以在HTTP Headers找到更多信息。


编辑

Tomcat 会自动设置一些头文件:

为了记录来自 Tomcat 的所有标头,您应该考虑this answer,它基本上说:

在 Host 或 Context 元素中放置一个 AccessLogValve,例如:

<Valve className="org.apache.catalina.valves.AccessLogValve"
 directory="logs" prefix="mysitelog." suffix=".txt" 
 pattern="..." resolveHosts="false" />

【讨论】:

  • 在我的doGet中,我没有给出任何response.addHeader。但是在浏览器的 Dev Console 中,我们仍然得到 3 个响应头。我们如何捕获这 3 个标头。我的要求是捕获所有 http 请求命中的请求和响应标头并将其放入日志文件中。所以我正在尝试使用过滤器来做到这一点。但在过滤器中,我只得到请求标头
  • 我明白了,我用更多信息更改了我的答案。
  • 我猜这只会写入日志文件。在写入日志之前,我需要执行一些处理。这就是为什么我试图在代码中捕获。处理意义上的,修改头部名称。或者将这些捕获的值发送到另一台服务器。我也尝试过 RequestDumperFilter,但没有捕获这些标头。
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 2012-09-25
  • 2011-09-19
  • 2011-11-25
  • 2021-12-31
  • 2011-01-09
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多