如果想用過濾器捕獲servlet對客戶端的響應輸出并且對它進行修改,就必須在響應被發(fā)送回客戶端之前,在服務器端緩存這個響應。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()//將響應數(shù)據(jù)用字符串返回
{
String s = null;
// Only return a String if the writer was
// used.
if (writer != null)
{
s = charWriter.toString();
}
return s;
}
public char[] toCharArray(){//將響應數(shù)據(jù)以字符數(shù)組返回
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>
運行圖: