如题,先上代码,代码很简单,一个将jsp输出内容转为大写字母的过滤器:
```public class UpperCaseFilter implements Filter {
private HttpServletRequest request;
private HttpServletResponse response;
public void init(FilterConfig config) throws ServletException {}
public void destroy() {}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
request = (HttpServletRequest) req;
response = (HttpServletResponse) resp;
ResponseWrapper responseWrapper = new ResponseWrapper(response);
chain.doFilter(request, responseWrapper);
String modifiedResponse = responseWrapper.toString().toUpperCase();
PrintWriter out = response.getWriter();
out.write(modifiedResponse);
//response.getOutputStream().println(modifiedResponse);
}
}
对输出内容进行包裹并缓存的类:
public class ResponseWrapper extends HttpServletResponseWrapper {
private StringWriter stringWriter;
public ResponseWrapper(HttpServletResponse response) {
super(response);
stringWriter = new StringWriter();
}
@Override
public PrintWriter getWriter() {
return (new PrintWriter(stringWriter));
}
@Override
public ServletOutputStream getOutputStream() {
return new ServletStream(stringWriter);
}
class ServletStream extends ServletOutputStream {
StringWriter stringWriter;
public ServletStream(StringWriter str) {
this.stringWriter = str;
}
@Override
public void write(int c) {
stringWriter.write(c);
}
}
public String toString() {
return (stringWriter.toString());
}
}
jsp文件的输出内容为几个小写字母,web.xml中注册了过滤器并映射到jsp文件,代码就不贴了。
现在问题来了,当我直接运行上面的代码的时候,能够输出大写字母;当我把ResponseWrapper类中的getOutputStream方法和ServletStream类注释掉后,仍然可以输出大写字母;当我把ResponseWrapper类中的getWriter方法注释掉,并且将UpperCaseFilter类中的最后两行换成后面的注释中的内容之后,运行会出现getWriter() has already been called for this response异常;当我把仅仅把UpperCaseFilter类中的最后两行换成后面的注释中的内容之后,又可以输出大写字母。
在上面的UpperCaseFilter中,我使用了两种方式获取输出对象,getWriter和getOutputStream,前面的描述的问题中可以看出,通过getWriter获得输出对象不依赖getOutputStream方法,反过来,通过getOutputStream获得输出对象要依赖getWriter方法。
现在,我就迷糊了,请问使用过滤器过滤输出内容的时候,执行过程具体是怎么样的?