Java ServletResponse和HttpServletResponseWrapper之间的区别?

Java ServletResponse和HttpServletResponseWrapper之间的区别?,java,servlets,wrapper,servlet-filters,Java,Servlets,Wrapper,Servlet Filters,我是servlet新手,正在阅读一些关于过滤器和包装器的文本。我能理解过滤器,但对包装器感到困惑。在书中,作者给出了一个例子: 如果没有包装: public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String name = re

我是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) {
        }
    }
public void doFilter(ServletRequest请求、ServletResponse响应、,
过滤链(链条)
抛出IOException、ServletException{
String name=request.getParameter(“name”).trim();
试一试{
链式过滤器(请求、响应);
PrintWriter out=response.getWriter();
if(name.length()==0){
out.println(“一些消息”);
out.println(“”);
out.println(“”);
out.close();
}
}捕获(可丢弃的t){
}
}
如果是包装纸:

 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) {
        }
    }
public void doFilter(ServletRequest请求、ServletResponse响应、,
过滤链(链条)
抛出IOException、ServletException{
String name=request.getParameter(“name”).trim();
HttpServletResponse HttpResponse=(HttpServletResponse)响应;
HttpServletResponseWrapper resWrapper=新的HttpServletResponseWrapper(httpRes);
试一试{
链式过滤器(请求、响应);
PrintWriter out=resWrapper.getWriter();//为什么不直接使用response.getWriter();
if(name.length()==0){
out.println(“一些消息”);
out.println(“”);
out.println(“”);
out.close();
}
}捕获(可丢弃的t){
}
}

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

这真是一个愚蠢的例子,没有显示请求/响应包装器的好处。实际上,整个过滤器示例都很差。发出HTML应该由JSP或servlet来完成(但这仍然很糟糕)。浏览我们的网站,了解过滤器的用途

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

在Stackoverflow上,您可以找到有用的
HttpServletResponseWrapper
实现示例


巴卢斯克的答案是好的,但如果你刚刚开始,可能会有点不知所措

简单地说:和它的扩展,是接口,告诉您可以调用什么方法来做您需要的事情。在使用过滤器、servlet等的正常过程中,您将经常使用HttpServletResponse来告诉您的应用程序如何响应请求

是HttpServletResponse的一个特定实现,它为您提供了一种方便的方法,可以使用自己的一些逻辑包装现有的响应,而无需编写接口的全新实现。它有很多方法,所以这真的很好。举一个简单的例子,假设您想禁止对的调用。此代码使用HttpServletResponseWrapper执行以下操作:

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

    @Override
    public void flushBuffer() {
        throw new UnsupportedOperationException("Don't call this!");
    }
}
使用此类包装器的典型方法是创建如下过滤器:

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);
        }
        ...
    }
    ...
}

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

这段代码看起来很奇怪。包装servlet响应的目的是进一步传递它(
chain.doFilter(request,resWrapper);
)并截获包装中的选定调用。例如,通过这种方式,您可以返回不同的响应编写器,动态更改或压缩内容,并将其发送到目标
响应
。这个例子没有多大意义。。。你能提供这本书的来源吗?我也觉得自己很奇怪。这段代码是我从一位大学讲师的powerpoint幻灯片中提取的。如果我们使用chain.doFilter(request,resWrapper),它会更有意义;正如您的建议,但是原始问题仍然没有得到回答,即为什么我们不能用原始的HttpServletResponse对象本身来完成所有这些?