核心提示:过滤器(filter)学习---全站压缩实例。理解过滤器过滤器,顾名思义就是用来过滤的肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的-Servlet只要是客户端请求服务器内的所有网页,...
过滤器(filter)学习---全站压缩实例。
理解过滤器
过滤器,顾名思义就是用来过滤的—肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的—-Servlet

只要是客户端请求服务器内的所有网页,Servlet.等。中间都可以设置一个过滤器。
如何写过滤器
1.实现一个过滤器的接口
public class GzipFilter implements Filter{
2.实现它的三个方法—用个做实际功能的

3.在web.xml中配置过滤器参数—用来设置拦截谁的
xml中和Servlet配置一样要配置两个参数


其中第一个:filte,和servlet类似
GzipFilter ---改过滤器名字cn.hncu.filters.GzipFilter ---改过滤器的类再哪
第二个:filter-mapping:- FORWARD
- INCLUDE
- REQUEST
- ASYNC
- ERROR
url-pattern---拦截的路径/*表示所有 dispatche---拦截以下这个中选 FORWARD、INCLUDE、REQUEST、ERROR、ASYNC 默认是REQUEST servlet-name---拦截那个Servlet 给名字就好了 GzipFilter /*
配置说明
过虑器的配置:以下几乎是所有单位的标准配置autoLoginFilter cn.itcast.autologinfilter.AutoLoginFilter filter-name是过虑器的名称 filter-class是过虑器的类文件 init-param是过虑器的初始化参数。 param-name – 是参数名。 param-value - 是参数值。 filter-mapping是过虑器的映射信息。 url-pattern-是需要过虑的资源url. autoLoginFilter /*
全站压缩实例
过滤器代码
package cn.hncu.filters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/*
* 全战压缩~ 思路:去之前把response加强了(带个容器),回来的时候把容器内的东西压缩了 再用原来response的输出去
*/
public class GzipFilter implements Filter{
@Override
public void init(FilterConfig paramFilterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest paramServletRequest,
ServletResponse paramServletResponse, FilterChain paramFilterChain)
throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) paramServletResponse;
MyResponse respone = new MyResponse(resp);
//用我们写的带容器的Myrespone 替换原来的
paramFilterChain.doFilter(paramServletRequest, respone);
//执行完了后,拿到源数据~
byte[] src_data =respone.getBout().toByteArray();
//测试一下源数据长度
System.out.println(src_data.length);
//通过gizp对源数据压缩
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bout);
gzip.write(src_data);
gzip.close();// 关流很重要不然会没数据啊~
byte[] gzip_data = bout.toByteArray();
//测试一下压缩后的数据长度
System.out.println(gzip_data.length);
//压缩完以后,再通过原来的response发送出去
resp.setHeader("Content-Encoding", "gzip");
resp.getOutputStream().write(gzip_data);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream bout = new ByteArrayOutputStream();
private PrintWriter writer = null;
public MyResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyOutputStream(bout);
}
@Override
public PrintWriter getWriter() throws IOException {
writer= new PrintWriter(new OutputStreamWriter(bout, "utf-8"),true);
return writer;
}
public ByteArrayOutputStream getBout(){
if(writer!=null){ // 这一句很重要,没有这个关流会导致网页很多数据在缓存内,网页无法显示
writer.close();
}
return bout;
}
}
class MyOutputStream extends ServletOutputStream{
private ByteArrayOutputStream bout = null;
public MyOutputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b); //把数据读到容器中区
}
}
web.xml
GzipFilter cn.hncu.filters.GzipFilter GzipFilter /* LoginServlet cn.hncu.servlet.LoginServlet WordServlet cn.hncu.servlet.WordServlet Gzip_Servlet cn.hncu.servlet.Gzip_Servlet LoginServlet /LoginServlet WordServlet /WordServlet Gzip_Servlet /Gzip_Servlet index.jsp
说明一下:因为真个网址会有两种流,字节流和字符流,我们要做到全站压缩就得兼容两种。其中有一些细节我已经写在代码注释里了


