【问题标题】:How to write response filter?如何编写响应过滤器?
【发布时间】:2011-08-03 19:37:21
【问题描述】:
有没有办法只处理过滤器中的响应。
下面写的代码正确吗?
public void doFilter(request , response , chain) {
//code to handle request
chain.doFilter(request, response);
//code to handle response .
}
【问题讨论】:
标签:
java
servlets
jakarta-ee
servlet-filters
【解决方案1】:
我使用以下代码集过滤了响应:
public void doFilter(request , response , chain) {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
CharResponseWrapper responseWrapper = new CharResponseWrapper(httpServletResponse);
ServletResponse newResponse = response;
if (request instanceof HttpServletRequest) {
newResponse = new CharResponseWrapper((HttpServletResponse) response);
}
chain.doFilter(request, newResponse);
if (newResponse instanceof CharResponseWrapper) {
String responseString = newResponse.toString();
if(StringUtils.isNotBlank(walletResponseString)) {
//code to handle response by converting to object
}
}
}
【解决方案2】:
Request 和 Responses 是只读的。所以他们没有 setter 方法来修改它的内容。但是通过使用 java 内置的“HttpServletRequestWrapper 和 HttpServletResponseWrapper”类我们可以修改它的内容。我们正在封装原始通过封装对象请求和响应对象,通过修改封装对象我们可以真正修改原始请求和响应对象。
【解决方案3】:
这取决于你想要什么。一般来说,你的样本是不正确的。在chain.doFilter 返回后,对响应做任何事情都为时已晚。此时,整个响应已经发送到客户端,您的代码无法访问它。
您需要做的是将request 和/或response 包装到您自己的类中,将这些包装器传递给doFilter 方法并处理包装器中的任何处理。
为了方便起见,servlet api 中已经提供了包装器:请参阅 HttpServletRequestWrapper 和 HttpServletResponseWrapper 类。如果要处理实际发送到客户端的输出,还需要编写自定义的 OutputStream 或 Writer 包装器,并从 HttpServletResponse 包装器中返回它们。是的,很多包装:)
一些更简单的过滤器可以在不包装请求或响应的情况下工作:例如在调用doFilter 之前,您已经可以访问请求标头,或者您可以在不调用doFilter 的情况下发送自定义响应。但是如果你想处理请求体,你不能仅仅阅读它,否则它将无法被链的其余部分使用。在这种情况下,您需要再次使用包装技术。
【解决方案4】:
您显示的代码并不完全正确,但对术语进行了必要的简化 - 确实如此。即使在 chain.doFilter(..) 之后(以及之前的响应),您也可以“处理”请求。
chain.doFilter(..)的意思是把进程传递给想要的目标,当方法返回时,目标已经完成了输出。
所以更准确地说 - 它是“之前”和“之后”请求已被处理并生成响应。
【解决方案5】:
您的代码似乎没问题。
如果你只想处理响应,你可以把你的代码放在//Code to handle response . 部分,然后做任何你喜欢的事情。
如果你想对输出做点什么,你必须提供一个特殊的响应包装器来处理 servlet(和其他过滤器)可能写入的响应中的输出流。