ServletResponse和HttpServletResponseWrapper之间的区别?

ipk*_*iss 13 java servlets wrapper servlet-filters

我是servlet的新手,并阅读有关过滤器和包装器的一些文本.我可以理解过滤器,但对包装器感到困惑.在书中,作者给出了一个例子:

如果没有包装:

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

        String name = request.getParameter("name").trim();

        try {
            chain.doFilter(request, response);
            PrintWriter out = response.getWriter();
            if (name.length() == 0) {
                out.println("Some message");
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        } catch (Throwable t) {
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果是包装:

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

        String name = request.getParameter("name").trim();

        HttpServletResponse httpRes = (HttpServletResponse) response;
        HttpServletResponseWrapper resWrapper = new HttpServletResponseWrapper(httpRes);
        try {
            chain.doFilter(request, response);

            PrintWriter out = resWrapper.getWriter(); // why dont we just use response.getWriter();
            if (name.length() == 0) {
                out.println("<h3>Some message");
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        } catch (Throwable t) {
        }
    }
Run Code Online (Sandbox Code Playgroud)

为什么我们需要,HttpServletResponseWrapperServletResponse在案例1中我们可以做同样的事情?谁能给我一个明确的例子,我们必须使用HttpServletResponseWrapper 而不是ServletResponse?我试过谷歌,但没有找到运气.

Rya*_*art 18

BalusC的答案很好,但如果你刚开始的话可能会有点压倒性的.

简单地说:SerlvetResponse及其扩展名HttpServletResponse是告诉你可以调用哪些方法来完成你需要的东西的接口.在使用Filters,Servlets等的正常过程中,您将经常使用HttpServletResponse告诉您的应用如何响应请求.

HttpServletResponseWrapperHttpServletResponse的一个特殊实现,它为您提供了一种方便的方法,可以使用您自己的逻辑来包装现有响应,而无需编写全新的接口实现.它有很多方法,所以这非常好.作为一个简单的例子,假设你想禁止调用response.flushBuffer().这段代码使用HttpServletResponseWrapper来实现:

class DisallowFlushResponseWrapper extends HttpServletResponseWrapper {
    public DisallowFlushResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void flushBuffer() {
        throw new UnsupportedOperationException("Don't call this!");
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这种包装器的典型方法是创建一个这样的过滤器:

class DisallowFlushFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) {
        if (response instanceof HttpServletResponse) {
            HttpServletResponse newResponse =
                new DisallowFlushResponseWrapper((HttpServletResponse) response);
            chain.doFilter(request, newResponse);
        }
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们使用自己的包装器实例将响应包装到过滤器中.然后我们将包装器向下移动到过滤器链中的下一个项目.因此,如果它调用flushBuffer(),那么在此过滤器之后出现的任何内容都将获得异常,因为它将在我们的包装器上调用它.由于其默认行为,包装器将委托对包装响应的任何其他调用,这是真实的,因此除了调用该方法之外的所有内容都将正常工作.


Bal*_*usC 10

这真是一个愚蠢的例子,没有显示请求/响应包装器的好处.实际上,整个过滤器示例很差.发送HTML应该由JSP或最高的servlet完成(但仍然很差).浏览我们的过滤器维基页面,了解过滤器的用途.

如果要修改响应的行为,或者只是想在请求 - 响应链中使用响应收集有关响应的信息,则响应包装器非常有用.每当某个servlet或JSP在响应上调用某个方法时,修改的行为就会被置换.如果你在包装器类中重写了它,那么将调用这个.您可以改变行为或收集信息.

在Stackoverflow上,您可以找到一些 有用实现的具体示例HttpServletResponseWrapper.


归档时间:

查看次数:

15097 次

最近记录:

14 年,1 月 前