java ServletResponse 和 HttpServletResponseWrapper 的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7023374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Differences between ServletResponse and HttpServletResponseWrapper?
提问by ipkiss
I am new to servlet and reading some text about filters and wrappers. I can understand filters but got confused about wrappers. In the book, the author gives an example:
我是 servlet 的新手,正在阅读有关过滤器和包装器的一些文本。我可以理解过滤器,但对包装器感到困惑。在书中,作者举了一个例子:
In case no wrapper:
如果没有包装器:
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) {
}
}
In case of wrapper:
在包装的情况下:
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) {
}
}
Why we need HttpServletResponseWrapper
while we can do the same thing with ServletResponse
in case 1? Can anyone give me a clear example that we MUST use HttpServletResponseWrapper
instead of ServletResponse
? I have tried to google but found no luck.
为什么我们需要,HttpServletResponseWrapper
而我们可以ServletResponse
在案例 1 中做同样的事情?谁能给我一个明确的例子,我们必须使用HttpServletResponseWrapper
而不是ServletResponse
?我试过谷歌,但没有找到运气。
回答by Ryan Stewart
BalusC's answer is good, but it might be a little overwhelming if you're just starting out.
BalusC 的回答很好,但如果您刚刚开始,可能会有点不知所措。
Put simply: SerlvetResponseand its extension, HttpServletResponse, are interfaces telling you what methods are available to call to do the things you need. In the normal course of working with Filters, Servlets, et al., you'll use HttpServletResponse often to tell your app how to respond to requests.
简单地说:SerlvetResponse及其扩展HttpServletResponse是接口,告诉您可以调用哪些方法来执行您需要的操作。在使用过滤器、Servlet 等的正常过程中,您会经常使用 HttpServletResponse 来告诉您的应用程序如何响应请求。
HttpServletResponseWrapperis one particular implementation of HttpServletResponse which gives you a convenient way to wrap an existing response with some logic of your own without having to write a whole new implementation of the interface. It has a lotof methods, so this is really nice. As a trivial example, suppose you wanted to disallow calls to response.flushBuffer(). This code, using HttpServletResponseWrapper, will do that:
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!");
}
}
The typical way to use such a wrapper would be to create a filter like 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);
}
...
}
...
}
Note that we wrap the response coming into the filter with an instance of our own wrapper. Then we hand the wrapper down to the next item in the filter chain. Thus anything that comes after this filter will get an exception if it calls flushBuffer() because it will be calling it on our wrapper. The wrapper, due to its default behavior, will delegate any other call to the wrapped response, which is the real one, so everything except calls to that one method will work normally.
请注意,我们使用我们自己的包装器实例包装了进入过滤器的响应。然后我们将包装器交给过滤器链中的下一个项目。因此,如果此过滤器之后的任何内容调用flushBuffer() 都会得到异常,因为它将在我们的包装器上调用它。由于其默认行为,包装器会将任何其他调用委托给包装的响应,这是真正的响应,因此除了调用该方法之外的所有内容都将正常工作。
回答by BalusC
That's really a stupid example which does not show the benefit of request/response wrapper. Actually, the whole filter example is poor. Emitting HTML should be done by a JSP or at highest a servlet (but also that is still poor). Go through our filters wiki pageto get some ideas about what a filter can be used for.
这确实是一个愚蠢的例子,它没有显示请求/响应包装器的好处。实际上,整个过滤器示例都很糟糕。发出 HTML 应该由 JSP 或最多由 servlet 完成(但这仍然很差)。浏览我们的过滤器维基页面,了解过滤器的用途。
A response wrapper is useful if you want to modify the response's behaviour or just want to collect information about the response whileit is been used in the request-response chain. The modified behaviour takes then place whenever some servlet or JSP calls a certain method on the response. If you have overriden it in your wrapper class, then this one will be called instead. You could alter the behaviour or collect information there.
如果要修改响应的行为,或者只是想约的响应收集信息的响应包装是有用的,而它是在请求-响应链被使用。每当某个 servlet 或 JSP 对响应调用某个方法时,就会发生修改后的行为。如果你在你的包装类中覆盖了它,那么这个将被调用。您可以在那里改变行为或收集信息。
Here on Stackoverflow you can find someconcreteexamples of useful HttpServletResponseWrapper
implementations.
在 Stackoverflow 上,您可以找到一些有用实现的具体示例HttpServletResponseWrapper
。
- How to insert JSF page rendering time and response size into the page itself, at least partially?
- MD5 Signing a HttpServletResponse
- How to configure Tomcat to not encode the session id into the URL when HttpServletResponse.encodeURL() is invoked
- How to add response headers based on Content-type; getting Content-type before the response is committed
- How is annotations support in jsp implemented in sitebricks?
- Capture and log the response body
- Log only http servlet response headers
- How to include a JSP page in a Facelets page?
- Capture generated dynamic content at server side