如果想用过滤器捕获servlet对客户端的响应输出并且对它进行修改,就必须在响应被发送回客户端之前,在服务器端缓存这个响应。Servlet API为我们提供了:
HttpServletResponseWrapper类
利用它我们可以截获响应并在本地缓存,然后想做什么就做什么。
下面是一个可重用的响应包装器:
/*
* CharResponseWrapper
*@author Karl Moss
*/
package com.omh.filters;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/**
* Simple response wrapper that utilizes a local CharArrayWriter
* for output
*/
public class CharResponseWrapper
extends HttpServletResponseWrapper
{
protected CharArrayWriter charWriter;//将响应缓存在这个写入器中
protected PrintWriter writer;
protected boolean getOutputStreamCalled;
protected boolean getWriterCalled;
public CharResponseWrapper(HttpServletResponse response)
{
super(response);
// Create the writer
charWriter = new CharArrayWriter();
}
public ServletOutputStream getOutputStream()
throws IOException
{
// Can't call getOutputStream if getWriter
// has already been called
if (getWriterCalled)
{
throw new IllegalStateException(
"getWriter already called");
}
getOutputStreamCalled = true;
return super.getOutputStream();
}
public PrintWriter getWriter()
throws IOException
{
if (writer != null)
{
return writer;
}
// Can't call getWriter if getOutputStream
// has already been called
if (getOutputStreamCalled)
{
throw new IllegalStateException(
"getOutputStream already called");
}
getWriterCalled = true;
writer = new PrintWriter(charWriter);
return writer;
}
public String toString()//将响应数据用字符串返回
{
String s = null;
// Only return a String if the writer was
// used.
if (writer != null)
{
s = charWriter.toString();
}
return s;
}
public char[] toCharArray(){//将响应数据以字符数组返回
return(charWriter.toCharArray());
}
}
利用上面包装器把一个servlet响应全部改变成大写形式:
/*
* UpperCaseFilter
* @author Karl Moss
*/
package com.omh.filters;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/**
* Filter that uses a response wrapper to convert all
* output to upper case
*/
public class UpperCaseFilter
implements Filter
{
protected FilterConfig config;
public void init(FilterConfig config)
throws ServletException
{
// Save the config object
this.config = config;
}
public void destroy()
{
}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws ServletException, IOException
{
ServletResponse newResponse = response;
// If this is an HttpRequest, wrap the response
// with our CharArrayWriter so that we can get
// the contents
if (request instanceof HttpServletRequest)
{
newResponse = new CharResponseWrapper(
(HttpServletResponse) response);
}
// Invoke the next filter/servlet in the chain
// using (perhaps) a wrapped response
chain.doFilter(request, newResponse);
if (newResponse instanceof CharResponseWrapper)
{
// Get the contents of the output. A String
// is returned only if a Writer was used,
// indicating text output. If getOutputStream
// was used the output will go to the "real"
// underlying output stream back to the client
String text = newResponse.toString();
if (text != null)
{
text = text.toUpperCase();
// Now write the output to the real
// output stream that goes back to
// the client
response.getWriter().write(text);
}
}
}
}
过滤器配置:
<filter>
<filter-name>Upper Case Filter</filter-name>
<filter-class>com.omh.filters.UpperCaseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Upper Case Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
运行图: