JSP学习笔记(第2次):Servlet过滤器

来源:互联网 发布:kk棋牌源码 编辑:程序博客网 时间:2024/05/19 03:45

1.过滤器的概念

Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。

优点:过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题

2.过滤器的应用

  • 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。
  • 根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。
  • 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。
  • 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
  • 3.Filter接口

    1.如何驱动

    在 web 应用程序启动时,web 服务器将根据 web.xml 文件中的配置信息来创建每个注册的 Filter 实例对象,并将其保存在服务器的内存中

    2.方法介绍

    init()  Init 方法在 Filter 生命周期中仅执行一次,web 容器在调用 init 方法时destory()  在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。doFilter() Filter 链的执行 

    以上三段转自:连接

4.过滤器的一些使用方法

4.1字符编码控制

如果每次servlet时都去设定中文字符编码,显然是非常麻烦的,用过滤器可以简化这个过程。

import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.annotation.WebInitParam;@WebFilter(filterName="filter01",urlPatterns="/*")//这里是设置Filter本身属性@WebInitParam(name="Encoding",value="UTF-8")//这里是通过注解来设置一些参数//当然这上面的一切在web.XML里完成也是一样的public class CharFilter implements Filter {    private String Encoding;    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        // TODO Auto-generated method stub        System.out.println("before filter");        //response.setContentType("text/html;charset="+Encoding+";pageEncoding="+Encoding);        response.setCharacterEncoding(Encoding);        //request.setCharacterEncoding(Encoding);        chain.doFilter(request, response);        System.out.println("end filter");    }    @Override    public void init(FilterConfig config) throws ServletException {        // 在init这个函数里执行字符编码的修改        String e=config.getInitParameter("Encoding");        //这里使用config对象来实现对init参数的获取        if(e==null||"".equals(e.trim())){            Encoding="UTF-8";        }        else{            Encoding=e;        }    }}

4.2在过滤器中完成对ThreadLocal对象的内参数的设置与删除

ThreadLocal对象非常有用,它可以在整个线程中有效,所以可以将一些表示层的变量存储到ThreadLocal中,此时可以在DAO层获取ThreadLocal中的数据,这样可以省略一些DAO层所需要的公共参数

如以下代码
定义一个类叫做SystemContext,在这个类中定义一系列的static的ThreadLocal变量。并且提供相应的get和set和remove方法

public class SystemContext {    private static ThreadLocal<Integer> pageSize = new ThreadLocal<Integer>();    private static ThreadLocal<Integer> pageIndex = new ThreadLocal<Integer>();    private static ThreadLocal<Integer> pageOffset = new ThreadLocal<Integer>();    //这段代码实为控制分页框架page-taglib参数的类,以上三个参数分别为每页多少条,当前页码,和开始页    public static int getPageOffset() {        return pageOffset.get();    }    public static void setPageOffset(int _pageOffset) {        pageOffset.set(_pageOffset);    }    public static void removePageOffset() {        pageOffset.remove();    }    public static void setPageSize(int _pageSize) {        pageSize.set(_pageSize);    }    public static int getPageSize() {        return pageSize.get();    }    public static void removePageSize() {        pageSize.remove();    }    public static void setPageIndex(int _pageIndex) {        pageIndex.set(_pageIndex);    }    public static int getPageIndex() {        return pageIndex.get();    }    public static void removePageIndex() {        pageIndex.remove();    }}

然后再定义一个过滤器,在里面完成对SystemContext 类的一些列操作

public class SystemContextFilter implements Filter {    int pageSize;    //这里设置了一个参数保存了每页有多少项    @Override    public void destroy() {    }    @Override    public void doFilter(ServletRequest req, ServletResponse resp,            FilterChain chain) throws IOException, ServletException {        try {            int pageOffset = 0;            int pageSize = 15;            try {                pageOffset = Integer.parseInt(req.getParameter("pager.offset"));            } catch (NumberFormatException e) {            }            SystemContext.setPageOffset(pageOffset);            SystemContext.setPageSize(pageSize);            chain.doFilter(req, resp);        } finally {            //在执行完页面后,释放掉存在于对应ThreadLocal对象里的参数            SystemContext.removePageOffset();            SystemContext.removePageSize();        }    }    @Override    public void init(FilterConfig cfg) throws ServletException {        try {            pageSize = Integer.parseInt(cfg.getInitParameter("pageSize"));        } catch (NumberFormatException e) {            pageSize = 15;        }    }}

4.3检查登录状态

使用过滤器可以简单的以一次代码编写就完成对多个特定页面的过滤,由于这种性质我们可以用来做一些检查,比如判断不同的用户有不同的权限,不同的权限在界面上给予不同的功能,这里完成一个比较简单的,但比较实用,验证用户的登入状态,如果用户属于非法的进入页面状态,转跳回登入界面。

public class AdminCheckFilter implements Filter {    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest request, ServletResponse resp,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest req = (HttpServletRequest)request;        //这里做强制类型转换是因为ServletRequest里没有getSession方法        HttpSession session = req.getSession();        //这里的用户如果登入了,会保存在内置对象Session里参数名为loginUser        //于是在这里获取它        User u = (User)session.getAttribute("loginUser");        //判断用户是否登入        if(u==null) {            respon.sendRedirect(req.getContextPath()+"/loginInput.jsp");            //用户没有登入转跳回登入界面            return;        }        chain.doFilter(request, resp);    }    @Override    public void init(FilterConfig arg0) throws ServletException {    }
0 0
原创粉丝点击