ServletResponse和HttpServletResponseWrapper之间的区别?

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

如果没有包装:

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(""); out.println(""); out.close(); } } catch (Throwable 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("

Some message"); out.println(""); out.println(""); out.close(); } } catch (Throwable t) { } }

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

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

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

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

 class DisallowFlushResponseWrapper extends HttpServletResponseWrapper { public DisallowFlushResponseWrapper(HttpServletResponse response) { super(response); } @Override public void flushBuffer() { throw new UnsupportedOperationException("Don't call this!"); } } 

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

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

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

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

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

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

  • 如何将JSF页面呈现时间和响应大小插入页面本身,至少部分?
  • MD5签署HttpServletResponse
  • 如何在调用HttpServletResponse.encodeURL()时将Tomcat配置为不将会话ID编码到URL中
  • 如何根据Content-type添加响应头; 在提交响应之前获取Content-type
  • 如何在sitebricks中实现的jsp中支持注释?
  • 捕获并记录响应正文
  • 仅记录http servlet响应标头
  • 如何在Facelets页面中包含JSP页面?
  • 捕获服务器端生成的动态内容