关闭

过滤器(filter)学习---全站压缩实例

标签: filter
74人阅读 评论(0) 收藏 举报
分类:

本篇博客知识点
1.理解过滤器
2.如何写过滤器
3.全站压缩实例

理解过滤器

过滤器,顾名思义就是用来过滤的—肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的—-Servlet
这里写图片描述

只要是客户端请求服务器内的所有网页,Servlet.等。中间都可以设置一个过滤器。

如何写过滤器

1.实现一个过滤器的接口

public class GzipFilter implements Filter{

2.实现它的三个方法—用个做实际功能的
这里写图片描述

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

这里写图片描述

其中第一个:filte,和servlet类似

<filter>
    <filter-name>GzipFilter</filter-name>---改过滤器名字
    <filter-class>cn.hncu.filters.GzipFilter</filter-class>---改过滤器的类再哪
   </filter>

第二个:filter-mapping:- FORWARD
- INCLUDE
- REQUEST
- ASYNC
- ERROR

 <filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher></dispatcher>
    <servlet-name></servlet-name>
  </filter-mapping>
  url-pattern---拦截的路径/*表示所有
  dispatche---拦截以下这个中选 FORWARD、INCLUDE、REQUEST、ERROR、ASYNC  默认是REQUEST
  servlet-name---拦截那个Servlet 给名字就好了

配置说明

过虑器的配置:以下几乎是所有单位的标准配置
<filter>
  <filter-name>autoLoginFilter</filter-name>
  <filter-class>cn.itcast.autologinfilter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>autoLoginFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
filter-name是过虑器的名称
filter-class是过虑器的类文件
init-param是过虑器的初始化参数。
param-name – 是参数名。
param-value - 是参数值。
filter-mapping是过虑器的映射信息。
url-pattern-是需要过虑的资源url.

全站压缩实例

过滤器代码

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

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name> 


    <filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>cn.hncu.filters.GzipFilter</filter-class>
   </filter>
  <filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>WordServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.WordServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Gzip_Servlet</servlet-name>
    <servlet-class>cn.hncu.servlet.Gzip_Servlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>WordServlet</servlet-name>
    <url-pattern>/WordServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Gzip_Servlet</servlet-name>
    <url-pattern>/Gzip_Servlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

说明一下:因为真个网址会有两种流,字节流和字符流,我们要做到全站压缩就得兼容两种。其中有一些细节我已经写在代码注释里了

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:30723次
    • 积分:2884
    • 等级:
    • 排名:第12550名
    • 原创:268篇
    • 转载:2篇
    • 译文:0篇
    • 评论:8条