Java 即使在使用ResponseWrapper之后,我们还需要将数据写入原始响应吗?

Java 即使在使用ResponseWrapper之后,我们还需要将数据写入原始响应吗?,java,servlets,Java,Servlets,我已经看到了许多关于如何和为什么包装响应的示例。据我所知,一个扩展了HttpServletResponseWrapper的类向servlet提供了一个流,用于在响应上写入数据(加上一些我们可以根据需要添加的附加方法)。这样servlet就可以在定制的响应流上写入数据 此外,在自定义类中,我们可以修改流内容,如;删除空间、大小写转换或压缩等,但只要servlet完成工作并关闭响应流,就可以执行任何此类操作。因此,基本上,自定义类仅用于保存响应数据。当控件从servlet返回过滤器时,我们需要在原始

我已经看到了许多关于如何和为什么包装响应的示例。据我所知,一个扩展了
HttpServletResponseWrapper
的类向servlet提供了一个流,用于在响应上写入数据(加上一些我们可以根据需要添加的附加方法)。这样servlet就可以在定制的响应流上写入数据

此外,在自定义类中,我们可以修改流内容,如;删除空间、大小写转换或压缩等,但只要servlet完成工作并关闭响应流,就可以执行任何此类操作。因此,基本上,自定义类仅用于保存响应数据。当控件从servlet返回过滤器时,我们需要在原始响应流上进一步写入数据

我以上理解的参考代码

CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);
response.setContentLength(caw.toString().length());
out.write(caw.toString());
out.close(); 
其他参考资料

现在请给我解释一下


它是否也不需要将数据写入响应流?请告诉我我遗漏了一些部分。

有两种方法:

  • 您描述的方法:将servlet编写的数据保存到某个临时缓冲区中,对其应用所需的修改,并在servlet完成后将其写入输出流

  • balusc的方法是:为动态执行所需修改的输出流创建一个包装器,并用它包装输出流。实际上,在balusc的示例中,它并不是实时工作的-在
    flush()
    操作期间,有一个临时缓冲区写入输出流


一般来说,后一种方法更好,因为它不需要额外的内存,也不引入延迟方面的开销。但是,对于复杂的修改可能很难实现。

理想情况下,响应包装器为写入输出流的内容执行某种类型的服务。在某些情况下,您可能还需要包装输出流。您可以通过重写响应包装器中的getOutputStream()方法(可能还有getWriter()方法)来实现这一点,以便它返回自定义outputstream(或Writer)。当内容写入自定义输出流(或写入器)时,您将执行以下三个操作之一(通常):

  • (可能修改数据并)将其写入原始输出流
  • 缓冲它(部分或全部),(可能修改数据并将其写入原始输出流
  • 完全丢弃数据(我确信在某个地方有这样的用例)
  • 您能否给出一些示例(不是代码,而是一些示例应用程序的名称),其中可能难以实现或很复杂。这会让我明白这个概念。
    HttpServletResponse httpres = (HttpServletResponse) response;
    chain.doFilter(request, wrapResponse(httpres, createTrimWriter(httpres)));