Servlet过滤器(Filter)

来源:互联网 发布:手动编程适用于 编辑:程序博客网 时间:2024/06/06 07:18

1过滤器的生命周期

a、应用被加载时就完成了过滤器的实例化和初始化,只有一次
b、针对用户的每次资源访问,容器都会调用doFilter方法
c、应用被卸载或服务器停止时,会执行destory方法
3、过滤器的参数配置FilterConfig

验证码和动态资源不要缓存,缓存与否,跟浏览器有关
写不要缓存的3个头

public class NoCacheFilter implements Filter {    public NoCacheFilter() {    }    public void destroy() {    }    //不要缓存文件,只要设置3个头就可以了,然后在web.xml里面进行配置即可    public void doFilter(ServletRequest req, ServletResponse resp,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) req;        HttpServletResponse response = (HttpServletResponse) resp;        response.setHeader("Expires", "-1");//只要比当前时间小就行,一般设置为-1        response.setHeader("Cache-Control", "no-cache");//1.1        response.setHeader("Pragma", "no-cache");//1.0        chain.doFilter(request, response);//别忘了放行    }

一、过滤器高级配置
page指令的错误页面,用的是转发技术
注意:servlet2.5有4个拦截选项,而servlet3.0有5个拦截选项
在web.xml中进行如下配置

    <filter>        <filter-name>FilterDemo</filter-name>        <filter-class>com.itheima.filter.FilterDemo</filter-class>    </filter>    <filter-mapping>        <filter-name>FilterDemo</filter-name>        <url-pattern>/*</url-pattern>        <!-- 所有错误都会被过滤 -->        <dispatcher>ERROR</dispatcher>        <!-- 所有转发都会被过滤-->        <dispatcher>FORWARD</dispatcher>        <!-- 所有动态包含都会被过滤 -->        <dispatcher>INCLUDE</dispatcher>        <!-- 所有请求都会被过滤 -->        <dispatcher>REQUEST</dispatcher>    </filter-mapping>    <error-page><!-- 配置错误页面 -->        <!-- 需要抓住的异常是什么类型 -->        <exception-type>java.lang.Exception</exception-type>        <!-- 出现错误后,需要转发到哪个页面 -->        <location>/error.jsp</location>    </error-page> 
全站压缩注意在进行配置文件设置的时候,只需要设置和文本相关的*.jsp;*.html,*.js;*.csspublic class GzipFilter implements Filter {    public void destroy() {    }    public void doFilter(ServletRequest arg1, ServletResponse arg2,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) arg1;        HttpServletResponse response = (HttpServletResponse) arg2;        GzipHttpServletResponse gresponse = new GzipHttpServletResponse(response);        chain.doFilter(request, gresponse);        //获取原始字节,进行压缩        byte[] b = gresponse.getBufferData();        System.out.println("压缩前的大小:"+b.length);//测试用        //建立一个byte[]输出流,关联到Gzip压缩流        ByteArrayOutputStream baos = new ByteArrayOutputStream();        //Gzip流需要一个字节输出流来关联,压缩流内的数据        GZIPOutputStream gos = new GZIPOutputStream(baos);        gos.write(b);        gos.close();        b = baos.toByteArray();//取出缓存中被压缩后的数据        System.out.println("压缩有的大小:"+b.length);        //告知浏览器压缩方式,就是设置头        response.setHeader("Content-Encoding", "gzip");        response.getOutputStream().write(b);    }    public void init(FilterConfig filterConfig) throws ServletException {    }}class GzipHttpServletResponse extends HttpServletResponseWrapper{    private ByteArrayOutputStream baos = new ByteArrayOutputStream();    private PrintWriter pw;    public GzipHttpServletResponse(HttpServletResponse response) {        super(response);    }    //servlet是使用getOutputStream获取流输出的    //覆盖这个方法,把数据写到一个缓存中,就可以进行获得数据    public ServletOutputStream getOutputStream() throws IOException {        ServletOutputStream sos = super.getOutputStream();        MyServletOutputStream msos = new MyServletOutputStream(sos,baos);        return msos;    }    //1如果是字符流则转成字符流,2把数据弄到baos中去    //查看API文档,PrintWriter的构造函数可以直接调用字符流进行输出    public PrintWriter getWriter() throws IOException {        pw = new PrintWriter(new OutputStreamWriter(baos, super.getCharacterEncoding()));        return pw;    }    public byte[] getBufferData() {        try {            //关闭Printwriter流            if(pw!=null)                pw.close();            baos.flush();        } catch (IOException e) {            e.printStackTrace();        }        return baos.toByteArray();    }}class MyServletOutputStream extends ServletOutputStream{    private ServletOutputStream sos;    private ByteArrayOutputStream baos;    public MyServletOutputStream(ServletOutputStream sos,ByteArrayOutputStream baos){        this.sos = sos;        this.baos = baos;    }    public void write(int b) throws IOException {        baos.write(b);    }

通过名字获取Cookie的工具类

package servlet;import javax.servlet.http.Cookie;public class CookUtils {        public static Cookie findCookie(Cookie[] cookies,String name){            if(cookies == null){                return null;            }else{                for (Cookie cookie : cookies) {                    if(cookie.getName().equals(name)){                        return cookie;                    }                }                return null;            }        }    }

自动登录的案例:

Servlet:

// 获得参数        User u = new User();        try {            BeanUtils.populate(u, request.getParameterMap());            UserService us = new UserService();            User eu = us.find(u);            if (eu == null) {                request.setAttribute("msg", "noman");                request.getRequestDispatcher("/login.jsp").forward(request, response);                return;            } else {                // 判断是否 选中 了 cookie                if ("ok".equals(request.getParameter("rem"))) {                    // 得到用户名和密码                    String value = u.getUsername() + "-" + u.getPassword();                    Cookie c = new Cookie("autoLogin", value);                    //设置访问的路径                    c.setPath("/");                    c.setMaxAge(60*60*8);                    // 添加到客户端                    response.addCookie(c);                }                //登陆到success.jsp                request.getSession().setAttribute("user", eu);                response.sendRedirect(request.getContextPath()+"/success.jsp");

filter 中的代码:

public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {      // 从session 拿出 user            HttpServletRequest req = (HttpServletRequest) request;          HttpServletResponse res = (HttpServletResponse) response;          User u = (User) req.getSession().getAttribute("user");          if(u==null) {              //拿出cookie  autoLongin                Cookie[] c = req.getCookies();              for(int x = 0;c!=null&&  x<c.length;x++) {                  if("autoLogin".equals(c[x].getName())){                      //找到了,到数据去比较                      String value = c[x].getValue();                      //得到name  和password                       String name = value.split("-")[0];                      String password = value.split("-")[1];                     UserDao ud = new UserDao();                     User uu = new User();                     uu.setUsername(name);                     uu.setPassword(password);                     User find = ud.find(uu);                     if(find==null) {//cookie 不对,放行                         chain.doFilter(request, response);                     }else {                         //把uu 存入session 中 ,就可以不用登陆了                         req.getSession().setAttribute("user", find);                         chain.doFilter(request, response);                         return;                     }                  }              }          }          chain.doFilter(request, response);
0 0
原创粉丝点击