JavaWeb Filter、Listener

丶灬走出姿态 提交于 2019-11-28 17:40:40

 

Filter

Servlet用于处理用户请求,Filter(过滤器)用于拦截request、response,对request、response对象进行修改,在Servlet处理请求前后实现某些功能。

 

 

 

Filter接口

Filter是一个实现了javax.servlet.Filter接口的类。

Filter接口中的方法:

  • init(FilterConfig  filterFonfig)    //初始化Filter
  • doFilter(ServletRequest request, ServletResponse response, FilterChain  chain)     //拦截、过滤。chain对象表示Filter链。此方法是Filter的关键方法。
  • destroy()   //在web服务器移除Filter对象之前调用,释放Filter对象占用的资源
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        //......    //去的时候拦截,做一些处理
        chain.doFilter(req, resp);  //放行
        //......    //回来的时候拦截,做一些处理
    }

 

 

 

 

Filter示例   统一全站编码

 1 @WebFilter("/*")
 2 public class HandlerFilter implements Filter {
 3     public void init(FilterConfig config){
 4     }
 5 
 6     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
 7         req.setCharacterEncoding("utf-8");
 8         resp.setContentType("text/html;charset=utf-8");
 9         chain.doFilter(req, resp);
10     }
11 
12     public void destroy() {
13     }
14 
15 }

 

 

 

 

Filter的配置

Filter的配置方式和Servlet的配置方式差不多。

(1)xml配置

<filter>
        <filter-name>handlerFilter</filter-name>
        <filter-class>filter.HandlerFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>handlerFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

(2)注解配置

@WebFilter("/*")
@WebFilter(filterName = "handlerFilter",urlPatterns = "/*")

 

 

 

 

Filter初始参数

在xml中配置Filter的初始参数:

<filter>
        <filter-name>handlerFilter</filter-name>
        <filter-class>filter.HandlerFilter</filter-class>
        <init-param>
            <param-name>name</param-name>
            <param-value>张三</param-value>
        </init-param>
        <init-param>
            <param-name>age</param-name>
            <param-value>20</param-value>
        </init-param>
    </filter>

 

或者在注解中配置:

@WebFilter(
        filterName = "handlerFilter",
        urlPatterns = "/*",
        initParams = {@WebInitParam(name = "name", value = "张三"),@WebInitParam(name="age",value = "12")}
        )

 

 

我们注意到Filter的init(FilterConfig config)有参数FilterConfig,Web服务器创建此Filter的实例时,会自动把xml或注解中这个Filter的初始参数以FilterConfig对象的形式注入。

 

在Filter中获取初始参数:

 1 public class HandlerFilter implements Filter {
 2     private FilterConfig filterConfig;   //需要创建一个成员变量
 3     public void init(FilterConfig config){
 4         this.filterConfig = config;  //需要我们手动初始化
 5     }
 6 
 7     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
 8         //获取单个初始参数的值
 9         String name = filterConfig.getInitParameter("name");  //返回值是String,不存在该参数时返回null
10         String age = filterConfig.getInitParameter("age");
11         System.out.println(name);
12         System.out.println(age);
13 
14         //遍历
15         Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
16         while (initParameterNames.hasMoreElements()){
17             String paramName = initParameterNames.nextElement();
18             String paramValue = filterConfig.getInitParameter(paramName);
19             System.out.println(paramValue);
20         }
21 
22         chain.doFilter(req, resp);
23     }
24 
25     public void destroy() {
26     }
27 
28 }

 

 

 

 

Filter示例   自动登录

思路:

使用cookie存储账号、密码,使用Filter拦截,从cookie中取出账号、密码。若用户要注销|登出、不再想使用自动登录,将cookie的有效期设置为0即可。

浏览器可以查看Cookie,不能直接存储账号、密码的明文,使用Cookie存储账号、密码时需要加密,从Cookie中取出来时需要解密。

每次HTTP请求都使用Filter拦截,从Cookie中解密出账号、密码,每次都要解密,浪费时间。第一次从Cookie中解密出账号、密码后,可以将账号、密码放到session域中,会话期间直接从session中取,不必再解密。

 

Servelt处理登录表单:

 1  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         //从登录表单中获取user、pwd
 3         String user=request.getParameter("user");
 4         String pwd=request.getParameter("pwd");
 5 
 6         //将user、pwd放到session域中
 7         HttpSession session = request.getSession();
 8         session.setAttribute("user",user);
 9         session.setAttribute("pwd",pwd);
10         
11         //对user、pwd进行加密
12         //......
13 
14         //将加密后的user、pwd存储到Cookie中,以后仍可使用
15         Cookie userCookie = new Cookie("user", user);
16         Cookie pwdCookie = new Cookie("pwd", pwd);
17         userCookie.setMaxAge(60*60*24*365);
18         pwdCookie.setMaxAge(60*60*24*365);
19         response.addCookie(userCookie);
20         response.addCookie(pwdCookie);
21 
22         //......
23     }

 

 

 

Filter拦截请求:

 1 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
 2         HttpServletRequest httpReq = (HttpServletRequest) req;  //ServletRequest不行,需要强转为HttpServletRequest
 3         HttpServletResponse httpResp = (HttpServletResponse) resp;
 4 
 5         HttpSession session = httpReq.getSession();
 6         String user = null;
 7         String pwd = null;
 8 
 9         if (session.getAttribute("user")==null){  //如果session中没有
10             //从Cookie中找
11             Cookie[] cookies = httpReq.getCookies();
12             for (Cookie cookie:cookies){
13                 //找到就添加到session域中,需要先解密,此处略过
14                 if (cookie.getName().equals("user")){
15                     user=cookie.getValue();
16                     session.setAttribute("user",cookie.getValue());
17                 }
18                 else if (cookie.getName().equals("pwd")){
19                     pwd=cookie.getValue();
20                     session.setAttribute("pwd",cookie.getValue());
21                 }
22             }
23 
24             //判断从Cookie中找到没
25             if (user==null){  //如果Cookie中也没有
26                 httpResp.getWriter().write("请先登录!3秒后自动跳转到登录页面");
27                 httpResp.setHeader("refresh","3;url=/login.jsp");
28             }
29             else{  //如果从Cookie中找到了,根据需要使用user、pwd
30                 //.......
31             }
32         }
33         else{  //如果session有,根据需要取出来使用
34             user= (String) session.getAttribute("user");
35             pwd = (String) session.getAttribute("pwd");
36             //......
37         }
38 
39         chain.doFilter(req, resp);
40     }

 

 

注销、登出、不再使用自动登录:

 1 //使用一个单独的Servlet来处理
 2     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 3         //从session域中移出user、pwd
 4         HttpSession session = request.getSession();
 5         session.removeAttribute("user");
 6         session.removeAttribute("pwd");
 7 
 8         //删除保存user、pwd的Cookie。这里使用同名覆盖,也可以遍历cookies获取。
 9         Cookie userCookie=new Cookie("user","");
10         Cookie pwdCookie=new Cookie("pwd","");
11         userCookie.setMaxAge(0);
12         pwdCookie.setMaxAge(0);
13         response.addCookie(userCookie);
14         response.addCookie(pwdCookie);
15     }

 

 

 

 

 

Listener

Listener是Servlet的事件监听器,一共有8个:

  • ServletContextListener    监听ServletContext对象的创建、销毁
  • HttpSessionListener   监听HTTPSession对象的创建、销毁
  • ServletRequestListener   监听ServletRequest对象的创建、销毁
  • ServletContextAttributeListener   监听ServletContext中属性的变化(添加属性、移除属性、修改属性)
  • HttpSessionAttributeListener
  • ServletRequestAttributeListener
  • HttpSessionBindListener   监听把JavaBean对象绑定到HttpSession对象上、把JavaBean对象从HttpSession对象上解绑
  • HttpSessionActivationListener  监听HttpSession中对象的活化、钝化

 

钝化:HttpSession对象从内存中转移至硬盘

活化:HttpSession对象从持久化状态转变为运行状态

 

以上监听器均为接口,自己新建Listener实现即可。

 

 

xml注册Listener:

<listener>
        <listener-class>listener.MyListener</listener-class>
    </listener>

监听的是整个web应用,不是某个Servlet。

 

 

注解注册Listener:

@WebListener()

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!