核心提示:过滤器(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
说明一下:因为真个网址会有两种流,字节流和字符流,我们要做到全站压缩就得兼容两种。其中有一些细节我已经写在代码注释里了