创建拦截器类,需要实现javax.servlet.Filter接口
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("服务器启动时调用此方法,只调用一次,用来初始化");
}
@Override
public void destroy() {
System.out.println("服务器退出时调用此方法,只调用一次");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain chain) throws IOException, ServletException {
//转换Request,Response类型
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response =(HttpServletResponse) arg1;
//使用自定义Response,由自定义内部类实现
MyResponse response1 = new MyResponse(response);
//解除拦截
chain.doFilter(request1, response1);
//处理Response中的流数据
byte[] bytes = response1.getBytes();
System.out.println("压缩前的数据大小:"+bytes+"------"+bytes.length);
byte[] bytess = GZIPByte.getGzipByte(bytes);
System.out.println("压缩后的数据大小:"+bytess.length);
//设置Response返回数据类型,设置消息头
response.setHeader("Content-Encoding","gzip");
response.getOutputStream().write(bytess);
}
}
自定义类继承HttpServletResponseWrapper类
注:HttpServletResponseWrapper类实现了HttpServletResponse接口
class MyResponse extends HttpServletResponseWrapper{
private HttpServletResponse response ;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response ;
}
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
//此方法用来返回ByteArrayOutputStream中的底层数据
public byte[] getBytes(){
if(printWriter!=null){
//这里一定要flush(),因为printWriter里有缓冲区,如果缓冲区没有满,则不会将数据存入ByteArrayOutputStream底层流中
printWriter.flush();
}
return baos.toByteArray();
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
//将数据不直接返回客户端,而是存入内存流
return new MyOutputStream(baos);
}
private PrintWriter printWriter = null;
@Override
public PrintWriter getWriter() throws IOException {
//利用OutputStreamWriter设置字符流的编码方式
printWriter = new PrintWriter(new OutputStreamWriter(baos,"utf-8"));
//将数据不直接返回客户端,而是存入内存流
return printWriter;
}
}
自定义内部类继承ServletOutputStream
class MyOutputStream extends ServletOutputStream{
private ByteArrayOutputStream baos;
public MyOutputStream(ByteArrayOutputStream baos){
this.baos = baos;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
baos.write(b, off, len);
}
@Override
public void write(byte[] b) throws IOException {
baos.write(b);
}
@Override
public void write(int b) throws IOException {
baos.write(b);
}
}
Util包中的GZIPByte工具类,用来压缩数据
public static byte[] getGzipByte(byte[] bs){
//定义一个内存流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
//定义一个GZIP压缩流,参数为内存流,将压缩到的数据存入底层的内存流
GZIPOutputStream gos = new GZIPOutputStream(baos);
gos.write(bs);
gos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
//返回压缩后的字节数据
return baos.toByteArray();
}
在web.xml中配置拦截器
<filter>
<filter-name>FilterDemo1</filter-name>
<filter-class>filter.demo.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo1</filter-name>
<!-- 拦截所有 -->
<url-pattern>/*</url-pattern>
</filter-mapping>