Servlets Servlet响应包装器将getHeaderNames和getHeaders方法添加到Servet2.4规范容器不工作

Servlets Servlet响应包装器将getHeaderNames和getHeaders方法添加到Servet2.4规范容器不工作,servlets,http-headers,httpresponse,response-headers,Servlets,Http Headers,Httpresponse,Response Headers,自Servlet 3.0以来,HttpServletResponse#getHeaderNames()和HttpServletResponse#getHeaders()已经可用。但是,我使用的是较旧的规范,特别是Servlet2.4 通过查看资源,我了解了如何编写包装器。如果我理解正确,我必须使用setHeader()来帮助创建getHeaderNames()和getHeaders()。我认为我对如何存储头以模拟这些缺少的方法的使用有着坚实的基础 问题是利用此包装的筛选器似乎没有自动调用setH

Servlet 3.0
以来,
HttpServletResponse#getHeaderNames()
HttpServletResponse#getHeaders()
已经可用。但是,我使用的是较旧的规范,特别是
Servlet2.4

通过查看资源,我了解了如何编写包装器。如果我理解正确,我必须使用
setHeader()
来帮助创建
getHeaderNames()
getHeaders()
。我认为我对如何存储头以模拟这些缺少的方法的使用有着坚实的基础

问题是利用此包装的筛选器似乎没有自动调用
setHeader()
。我不明白。我想既然
getStatus()
工作正常,我希望
setHeader()
也能以同样的方式工作。具体地说,我希望在调用
chain.doFilter()
之后打印出所有响应头。我不确定我做错了什么。可能我存储头名称-值对的方式有问题

我将感谢任何帮助。多谢各位

public class ServletResponseWrapper extends HttpServletResponseWrapper {

    private int httpStatus = SC_OK;
    private HashMap<String, String> hashMapHeaders = new HashMap<String, String>();

    public ServletResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendError(int sc) throws IOException {
        httpStatus = sc;
        super.sendError(sc);
    }

    @Override
    public void sendError(int sc, String msg) throws IOException {
        httpStatus = sc;
        super.sendError(sc, msg);
    }


    @Override
    public void setStatus(int sc) {
        httpStatus = sc;
        super.setStatus(sc);
    }

    public int getStatus() {
        return httpStatus;
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        httpStatus = SC_MOVED_TEMPORARILY;
        super.sendRedirect(location);
    }

    @Override
    public void setHeader(String name, String value) {
        hashMapHeaders.put(name, value);
        super.setHeader(name, value);
    }

    public String getHeader(String name) {
        return hashMapHeaders.get(name);
    }


    public Enumeration<String> getHeaderNames() {
        Enumeration<String> enumerationHeaderNames = Collections.enumeration(hashMapHeaders.keySet());
        return enumerationHeaderNames;
    }

}

public class ServletResponseWrapperFilter implements Filter {

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

        ServletResponseWrapper servletResponseWrapper = new ServletResponseWrapper( (HttpServletResponse) response );
        chain.doFilter( request, servletResponseWrapper );

        // Process response

        // This works, even though I never explicitly call the setStatus() method
        int status = response.getStatus();

        // This returns NULL because no header values get set; I presume setHeader() gets called implicitly
        Enumeration<String> headerNames = servletResponseWrapper.getHeaderNames();
    }

    public void init(FilterConfig config) throws ServletException {
        //empty
    }

    public void destroy() {
        // empty
    }
}
公共类ServletResponseWrapper扩展了HttpServletResponseWrapper{
私有int httpStatus=SC_OK;
私有HashMap hashMapHeaders=新HashMap();
公共ServletResponseWrapper(HttpServletResponse){
超级(响应);
}
@凌驾
公共void发送错误(int sc)引发IOException{
httpStatus=sc;
超级发送错误(sc);
}
@凌驾
public void sendError(int sc,String msg)引发IOException{
httpStatus=sc;
超级发送错误(sc,msg);
}
@凌驾
公共状态(内部sc){
httpStatus=sc;
super.setStatus(sc);
}
public int getStatus(){
返回httpStatus;
}
@凌驾
公共void sendRedirect(字符串位置)引发IOException{
httpStatus=SC\u临时移动;
super.sendRedirect(位置);
}
@凌驾
public void setHeader(字符串名称、字符串值){
hashMapHeaders.put(名称、值);
super.setHeader(名称、值);
}
公共字符串getHeader(字符串名称){
返回hashMapHeaders.get(name);
}
公共枚举getHeaderNames(){
枚举enumerationHeaderNames=Collections.Enumeration(hashMapHeaders.keySet());
返回enumerationHeaderNames;
}
}
公共类ServletResponseWrapperFilter实现过滤器{
public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException{
ServletResponseWrapper ServletResponseWrapper=新ServletResponseWrapper((HttpServletResponse)响应);
doFilter(请求,servletResponseWrapper);
//过程响应
//尽管我从未显式调用setStatus()方法,但这是可行的
int status=response.getStatus();
//这将返回NULL,因为未设置任何头值;我假定setHeader()被隐式调用
枚举headerNames=servletResponseWrapper.getHeaderNames();
}
public void init(FilterConfig config)抛出ServletException{
//空的
}
公共空间销毁(){
//空的
}
}
web.xml文件

<display-name>Tomcat App</display-name>

<filter>
    <filter-name>ResponseHeadersFilter</filter-name>
    <filter-class>com.company.filters.ResponseHeadersFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ResponseHeadersFilter</filter-name>
    <url-pattern>/testfilter.jsp</url-pattern>
</filter-mapping>

Tomcat应用程序
响应头过滤器
com.company.filters.ResponseHeadersFilter
响应头过滤器
/testfilter.jsp

我从等式中去掉了供应商的servlet。过滤器现在在空JSP文件上启动。Tomcat还连接到前端web服务器IIS。我禁用了IIS。现在,我通过8080端口直接通过Tomcat访问该网站。尽管如此,我看不到任何响应标题

使用Fiddler,我看到的响应头很少,但仍然存在,即:

  • (缓存)日期
  • (实体)内容-长度、内容类型
  • (杂项)服务器
  • 和状态响应,即HTTP/1.1 200 OK

我不需要在过滤器中获取响应标题就可以通过。但我有一个大问题,这是Servlet版本2.4的一个bug,或者我需要启用某种OS服务器和/或Tomcat配置更改吗?除非有一些Tomcat配置,否则我相信这可能是一个bug。也许使用我正在使用的Tomcat版本5.5.28的默认配置进行干净的安装可以解决这个问题,但我现在无法尝试这样做。

是您编写的处理响应的代码吗?你能给我看看吗?不幸的是,不能。这不是我写的。这是一个由供应商编写的相当复杂的servlet。我的过滤器和包装器代码看起来还好吗?我还想添加我注释掉了所有现有的过滤器声明和映射,除了这里的一个。即使我没有,也只有一个过滤器映射到供应商的servlet——同样,这里讨论的就是这个过滤器。那么,执行顺序不应该有冲突。仍然没有响应头。可能是Servlet2.4的错误?过滤器和包装器的代码看起来还可以。你能发布你的web.xml吗?有6种方法可以操作响应头。你只覆盖了其中一个。也试试其他人。