java web 之 listen 与 filterjava web 之 listen 与 filter

监听它们的创建与销毁、属性变化 以及session绑定javaBean,监听它们的创建与销毁、属性变化 以及session绑定javaBean

一、Listener监听器

Javaweb开发中之监听器,是用以监听web常见对象 HttpServletRequest HttpSession
ServletContext

监听它们的创造同销毁、属性变化 以及session绑定javaBean

1、监听机制

  • 事件  就是一个事情
  • 事件源  产生这业务的源
  • 监听器  用于监听指定的轩然大波之对象
  • 报监听 要想为监听器可以监听到事件发生,必须对该进行挂号。

2、Javaweb开发被时表现监听器

2.1、监听域对象的创办及销毁

  • 监听ServletContext创建同销毁  ServletContextListener
  • 监听HttpSession创建及销毁  HttpSessionListener
  • 监听HttpServletRequest创建与销毁  ServletRequestListener

2.2、监听域对象的习性变化

  • 监听ServletContext属性变化  ServletContextAttributeListener
  • 监听HttpSession属性变化  HttpSessionAttributeListener
  • 监听HttpServletRequest属性变化  ServletRequestAttributeListener

2.3、监听session绑定javaBean

它们是用以监听javaBean对象是否绑定到了session域   HttpSessionBindingListener

它是用来监听javaBean对象的活化与钝化
 HttpSessionActivationListener

3、监听器的飞入门

有关创建一个监听器的步调

  1. 创建一个类似,实现指定的监听器接口
  2. 重写接口中的方
  3. 以web.xml文件被对监听器进行挂号。
  4. ServletContext对象的始建及销毁

3.1、关于域对象创建与销毁之演示

本条目标是当服务器启动时创造的,在服务器关闭时销毁之。

HttpSession对象的创办与销毁

HttpSession session=request.getSession();

Session销毁 的方法

  1. 默认超时  30分钟
  2. 关门服务器
  3. invalidate()方法
  4. setMaxInactiveInterval(int interval) 可以设置过时间

题目:直接看一个jsp页面时,是否会见创session?

会创造,因为咱们默认情况下是足以在jsp页面中一直使用session内置对象的。

HttpServletRequest创建同销毁

Request对象是殡葬请求服务器即见面创造它,当响应产生时,request对象就会见销毁。

3.2、演示了Request域对象被性能变化

以java的监听机制中,它的监听器中之不二法门还是发参数的,参数就是事件目标,而我辈可由此波目标直接获得事件源。

3.3、**演示session绑定javaBean**

1、javaBean对象活动感知被绑定到session中.

HttpSessionBindingListener 这个接口是由javaBean实现的,并且不需要在web.xml文件被注册.

2、javabean对象好活化或钝化到session中。

HttpSessionActivationListener如果javaBean实现了这接口,那么当我们如常关闭服务器时,session中之javaBean对象就是会于钝化到我们指定的公文被。

即时一模一样涂鸦当起步服务器,因为咱们就拿目标写副到文件中,这时就会自行将javaBean对象活化到session中。

咱尚需要只context.xml文件来配置钝化时存储的文件

当meta-inf目录下创办一个context.xml文件

<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>

一、Listener监听器

Javaweb开发中的监听器,是用于监听web常见对象 HttpServletRequest HttpSession
ServletContext

监听它们的始建和销毁、属性变化 以及session绑定javaBean

1、监听机制

  • 事件  就是一个事务
  • 事件源  产生是事情的源头
  • 监听器  用于监听指定的波的靶子
  • 注册监听 要惦记让监听器可以监听到事件时有发生,必须对其展开注册。

2、Javaweb开发被时表现监听器

2.1、监听域对象的创同销毁

  • 监听ServletContext创建和销毁  ServletContextListener
  • 监听HttpSession创建与销毁  HttpSessionListener
  • 监听HttpServletRequest创建和销毁  ServletRequestListener

2.2、监听域对象的性变化

  • 监听ServletContext属性变化  ServletContextAttributeListener
  • 监听HttpSession属性变化  HttpSessionAttributeListener
  • 监听HttpServletRequest属性变化  ServletRequestAttributeListener

2.3、监听session绑定javaBean

其是用来监听javaBean对象是不是绑定到了session域   HttpSessionBindingListener

它们是用于监听javaBean对象的活化和钝化
 HttpSessionActivationListener

3、监听器的高速入门

关于创建一个监听器的步骤

  1. 缔造一个看似,实现指定的监听器接口
  2. 重写接口中之方法
  3. 于web.xml文件被针对监听器进行注册。
  4. ServletContext对象的创始与销毁

3.1、关于域对象创建同销毁的言传身教

是目标是当服务器启动时创造的,在服务器关闭时销毁之。

HttpSession对象的创同销毁

HttpSession session=request.getSession();

Session销毁 的方法

  1. 默认超时  30分钟
  2. 关闭服务器
  3. invalidate()方法
  4. setMaxInactiveInterval(int interval) 可以设置过时间

题目:直接看一个jsp页面时,是否会面创session?

见面创造,因为咱们默认情况下是可以以jsp页面中直接用session内置对象的。

HttpServletRequest创建和销毁

Request对象是殡葬请求服务器就会创造它,当响应产生时,request对象就会见销毁。

3.2、演示了Request域对象被性能变化

当java的监听机制中,它的监听器中之方还是有参数的,参数就是事件目标,而我辈好透过波目标直接得到事件源。

3.3、**演示session绑定javaBean**

1、javaBean对象活动感知被绑定到session中.

HttpSessionBindingListener 这个接口是由javaBean实现的,并且不需要在web.xml文件被注册.

2、javabean对象好活化或钝化到session中。

HttpSessionActivationListener如果javaBean实现了这个接口,那么当我们如常关闭服务器时,session中之javaBean对象就是会叫钝化到我们指定的公文被。

即时同一不行当起步服务器,因为我们早就将目标写副到文件被,这时便会自行将javaBean对象活化到session中。

咱还待个context.xml文件来安排钝化时存储的文书

当meta-inf目录下创造一个context.xml文件

<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>

案例-定时销毁session

1、怎样可以将每一个开立的session全都保存起来?

咱们好举行一个HttpSessionListener,当session对象创建时,就以这session对象装入到一个凑合中.

将集合List<HttpSession>保存到ServletContext域中。

2、怎样可以看清session过期了?

每当HttpSession中有一个艺术public long
getLastAccessedTime()

它好博session对象最后动用的时光,可以运用invalidate方法销毁。

ps(我们地方的操作需要用任务调度功能.)在java中发出一个Timer定时器类

 

package com.timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TestTimer {
    public static void main(String[] args) {
        Timer t = new Timer();

        t.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println(new Date().toLocaleString());
            }
        }, 2000, 1000);
    }
}

有关三个域对象获得

假定以Servlet中如取request,在方及便出,request.getSession() 
getServletContext();

若我们出request对象了,  request.getSession()
   request.getSession().getServletCotnext();

 

public class MySessionListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent arg0) {
        HttpSession session = arg0.getSession();
        //得到application中的list集合
        ServletContext application = session.getServletContext();
        //得到session对象,并放入list集合
        List<HttpSession> list =(List<HttpSession>) application.getAttribute("sessions");
        list.add(session);
        System.out.println("添加了"+session.getId());
    }
    public void sessionDestroyed(HttpSessionEvent arg0) {
        // TODO Auto-generated method stub
    }

}

次第在使时,需要考虑并发问题,因为我们于web中,它自然是一个差不多线程的,那么我们的顺序对聚集进行了长,还有移除操作。具体以MyServletContextListener的章程吃如下

public class MyServletContextListener implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent arg0) {   
    }
    public void contextInitialized(ServletContextEvent arg0) {
        //通過事件原對象得到事件源
            ServletContext application = arg0.getServletContext();
            //创建一个集合 存储所有session对象
            final List<HttpSession> list = Collections.synchronizedList(new ArrayList<HttpSession>());
            application.setAttribute("sessions", list);
            //创建一个计时器对象
            Timer t = new Timer();
            t.schedule(new TimerTask() {

                @Override
                public void run() {
                    System.out.println("开始扫描");
                    for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                        HttpSession session = (HttpSession) iterator.next();
                        long l = System.currentTimeMillis() - session.getLastAccessedTime();
                        if(l > 5000){
                            System.out.println("session移除了"+session.getId());
                            session.invalidate();
                            iterator.remove();
                        }
                    }
                }
            }, 2000, 5000);    
    }
}

案例-定时销毁session

1、怎样可以以各一个开立的session全都保存起来?

我们得以开一个HttpSessionListener,当session对象创建时,就用此session对象装入到一个集聚中.

将集合List<HttpSession>保存到ServletContext域中。

2、怎样可以断定session过期了?

当HttpSession中来一个方式public long
getLastAccessedTime()

她可取得session对象最后使的日子,可以行使invalidate方法销毁。

ps(我们地方的操作需要以任务调度功能.)在java中生出一个Timer定时器类

 

package com.timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TestTimer {
    public static void main(String[] args) {
        Timer t = new Timer();

        t.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println(new Date().toLocaleString());
            }
        }, 2000, 1000);
    }
}

有关三个域对象获得

如若以Servlet中一经博得request,在方及即出,request.getSession() 
getServletContext();

要是我们有request对象了,  request.getSession()
   request.getSession().getServletCotnext();

 

public class MySessionListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent arg0) {
        HttpSession session = arg0.getSession();
        //得到application中的list集合
        ServletContext application = session.getServletContext();
        //得到session对象,并放入list集合
        List<HttpSession> list =(List<HttpSession>) application.getAttribute("sessions");
        list.add(session);
        System.out.println("添加了"+session.getId());
    }
    public void sessionDestroyed(HttpSessionEvent arg0) {
        // TODO Auto-generated method stub
    }

}

程序在行使时,需要考虑并发问题,因为我们当web中,它必然是一个几近线程的,那么我们的次序对聚集进行了增长,还有移除操作。具体以MyServletContextListener的点子被如下

public class MyServletContextListener implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent arg0) {   
    }
    public void contextInitialized(ServletContextEvent arg0) {
        //通過事件原對象得到事件源
            ServletContext application = arg0.getServletContext();
            //创建一个集合 存储所有session对象
            final List<HttpSession> list = Collections.synchronizedList(new ArrayList<HttpSession>());
            application.setAttribute("sessions", list);
            //创建一个计时器对象
            Timer t = new Timer();
            t.schedule(new TimerTask() {

                @Override
                public void run() {
                    System.out.println("开始扫描");
                    for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                        HttpSession session = (HttpSession) iterator.next();
                        long l = System.currentTimeMillis() - session.getLastAccessedTime();
                        if(l > 5000){
                            System.out.println("session移除了"+session.getId());
                            session.invalidate();
                            iterator.remove();
                        }
                    }
                }
            }, 2000, 5000);    
    }
}

二、Filter

 

二、Filter

 

二、Filter过滤器(重要)

Javaweb中之过滤器可以阻碍所有访问web资源的呼吁或响应操作。

1.1、步骤:

  1. 缔造一个看似实现Filter接口
  2. 重写接口中方法  doFilter方法是真正过滤的。
  3. 每当web.xml文件中布局

瞩目:在Filter的doFilter方法内如果没有履chain.doFilter(request,response),那么资源是匪会见于看到的。

二、Filter过滤器(重要)

Javaweb中之过滤器可以阻挡所有访问web资源的伸手或响应操作。

1.1、步骤:

  1. 始建一个近似实现Filter接口
  2. 重写接口中方法  doFilter方法是确实过滤的。
  3. 每当web.xml文件被布置

小心:在Filter的doFilter方法内如果没实行chain.doFilter(request,response),那么资源是免会见被访问到之。

1.2、FilterChain

FilterChain 是 servlet
容器为开发人员提供的对象,它提供了针对性某个平资源的都过滤请求调用链的视图。过滤器使用
FilterChain
调用链中的下一个过滤器,如果调用的过滤器是链中的最终一个过滤器,则调整用链末尾的资源。

问题:怎样可以形成一个Filter链?

  只要多独Filter对同一个资源进行拦阻就好形成Filter链

题材:怎样确定Filter的履各个?

  由<filter-mapping>来确定

1.2、FilterChain

FilterChain 是 servlet
容器为开发人员提供的对象,它提供了针对性有平等资源的都过滤请求调用链的视图。过滤器使用
FilterChain
调用链中的产一个过滤器,如果调用的过滤器是链中的末尾一个过滤器,则调整用链末尾的资源。

题目:怎样可以形成一个Filter链?

  只要多单Filter对同一个资源进行阻挠就足以形成Filter链

题材:怎样确定Filter的实行各个?

  由<filter-mapping>来确定

1.3、Filter生命周期

Servlet生命周期:

实例化 –》 初始化 –》 服务 –》 销毁

  • 1 当服务器启动,会创Filter对象,并调用init方法,只调用相同浅.
  • 2
    当访问资源时,路径和Filter的阻路径匹配,会实施Filter中的doFilter方法,这个办法是确实拦截操作的方法.
  • 3 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.

1.3、Filter生命周期

Servlet生命周期:

实例化 –》 初始化 –》 服务 –》 销毁

  • 1 当服务器启动,会创Filter对象,并调用init方法,只调用相同蹩脚.
  • 2
    当访问资源时,路径和Filter的阻碍路径匹配,会执行Filter中之doFilter方法,这个主意是的确拦截操作的方法.
  • 3 当服务器关闭时,会调用Filter的destroy方法来展开销毁操作.

1.4、FilterConfig

于Filter的init方法齐发一个参数,类型就是FilterConfig.

FilterConfig它是Filter的布对象,它可以完成下列功能

  1. 获取Filtr名称
  2. 获得Filter初始化参数
  3. 获取ServletContext对象。

澳门蒲京网址 1

题目:怎样当Filter中得一个FIlterConfig对象?

 1 package com.itheima.filter;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 
12 public class MyFilterConfigTest implements Filter{
13 
14     private FilterConfig filterConfig;
15 
16     public void init(FilterConfig filterConfig) throws ServletException {
17         this.filterConfig = filterConfig;
18     }
19 
20     public void doFilter(ServletRequest request, ServletResponse response,
21             FilterChain chain) throws IOException, ServletException {
22         //通过FilterConfig对象获取到配置文件中的初始化信息
23         String encoding = filterConfig.getInitParameter("encoding");
24         System.out.println(encoding);
25         request.setCharacterEncoding(encoding);
26         //放行
27         chain.doFilter(request, response);
28     }
29 
30     public void destroy() {
31         // TODO Auto-generated method stub
32     }
33 }

如下 web.xml配置
<filter>
    <filter-name>MyFilterConfigTest</filter-name>
    <filter-class>com.itheima.filter.MyFilterConfigTest</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>MyFilterConfigTest</filter-name>
    <servlet-name>ServletDemo2</servlet-name>
</filter-mapping>

1.4、FilterConfig

每当Filter的init方法及发一个参数,类型就是FilterConfig.

FilterConfig它是Filter的配置对象,它可以形成下列功能

  1. 获取Filtr名称
  2. 获Filter初始化参数
  3. 获取ServletContext对象。

澳门蒲京网址 2

题目:怎样当Filter中获得一个FIlterConfig澳门蒲京网址对象?

 1 package com.itheima.filter;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 
12 public class MyFilterConfigTest implements Filter{
13 
14     private FilterConfig filterConfig;
15 
16     public void init(FilterConfig filterConfig) throws ServletException {
17         this.filterConfig = filterConfig;
18     }
19 
20     public void doFilter(ServletRequest request, ServletResponse response,
21             FilterChain chain) throws IOException, ServletException {
22         //通过FilterConfig对象获取到配置文件中的初始化信息
23         String encoding = filterConfig.getInitParameter("encoding");
24         System.out.println(encoding);
25         request.setCharacterEncoding(encoding);
26         //放行
27         chain.doFilter(request, response);
28     }
29 
30     public void destroy() {
31         // TODO Auto-generated method stub
32     }
33 }

如下 web.xml配置
<filter>
    <filter-name>MyFilterConfigTest</filter-name>
    <filter-class>com.itheima.filter.MyFilterConfigTest</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>MyFilterConfigTest</filter-name>
    <servlet-name>ServletDemo2</servlet-name>
</filter-mapping>

1.5、Filter配置

基本配备

<filter>
<filter-name>filter名称</filter-name>
<filter-class>Filter类的包名.类名</filter-class>
</filter>
<filter-mapping>
<filter-name>filter名称</filter-name>
<url-pattern>路径</url-pattern>
</filter-mapping>

 

有关其他配置

1.5、Filter配置

主导配备

<filter>
<filter-name>filter名称</filter-name>
<filter-class>Filter类的包名.类名</filter-class>
</filter>
<filter-mapping>
<filter-name>filter名称</filter-name>
<url-pattern>路径</url-pattern>
</filter-mapping>

 

关于其他配置

1.<url-pattern>

全盘匹配配   以”/demo1”开始,不包含通配符*

目录匹配   以”/”开始  以*结束

恢宏名匹配  *.xxx  不能够写成/*.xxx

1.<url-pattern>

全配合配   以”/demo1”开始,不含有通配符*

目录匹配   以”/”开始  以*结束

扩张名匹配  *.xxx  不能够写成/*.xxx

2.<servlet-name>

她是针对性点名的servlet名称的servlet进行阻拦的。

2.<servlet-name>

其是本着点名的servlet名称的servlet进行阻挠的。

3.<dispatcher>

可拿走之价值有  REQUEST  FORWARD  ERROR  INCLUDE    根据跳转方式阻碍

她的来意是:当为什么方法去访问web资源时,进行阻拦操作.

1.REQUEST
当是从浏览器直接看资源,或是重定向到某个资源时展开拦方式部署的
它吧是默认值

2.FORWARD 其讲述的凡央转发的阻碍方式安排

3.ERROR
要是目标资源是透过声明式异常处理体制调用时,那么该过滤器将让调用。除此之外,过滤器不会见叫调用。

4.INCLUDE
假如目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将让调用。除此之外,该过滤器不见面受调用

3.<dispatcher>

可以拿走的价值有  REQUEST  FORWARD  ERROR  INCLUDE    根据跳转方式阻碍

其的企图是:当因为什么方法去拜谒web资源时,进行阻挠操作.

1.REQUEST
当是从浏览器直接看资源,或是重定向到某个资源时开展阻挠方式安排的
它为是默认值

2.FORWARD 其描述的凡央转发的阻碍方式配置

3.ERROR
要是目标资源是由此声明式异常处理体制调用时,那么该过滤器将为调用。除此之外,过滤器不会见让调用。

4.INCLUDE
假如目标资源是经过RequestDispatcher的include()方法访问时,那么该过滤器将让调用。除此之外,该过滤器不会见受调用

 三、自动登录  (PS bean的属于性名和数据库里的字段名千万比方一致哦 不然会emmm 很无助)

  1. 当用户登陆成功后,判断是否勾选了全自动登陆,如果勾选了,就用用户称及密码持久化存储到cookie
  2. 召开一个Filter,对需要活动登陆的资源开展阻拦

首形容如于登录Servlet中登录成功时拿登录的信息保存在cookie里,并安装存活时间

if(null != user){
            String autologin = request.getParameter("autologin");

            Cookie cookie = new Cookie("user", user.getUsername()+"&"+user.getPassword());
            cookie.setPath("/");
            if(autologin != null){// on / null
                cookie.setMaxAge(60*60*24*7);
            }else{
                cookie.setMaxAge(0);
            }
            response.addCookie(cookie);
            request.getSession().setAttribute("user", user);
            request.getRequestDispatcher("/home.jsp").forward(request, response);
        }

 然后安好filter类 记住要在web.xml里面配备  如下 为 doFilter代码

public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        //1、转换对象
        HttpServletRequest req = (HttpServletRequest) arg0;
        //2、处理业务
        Cookie[] cookies = req.getCookies();
        String username = "";
        String password = "";
        for (int i = 0;cookies!=null && i < cookies.length; i++) {
            if("user".equals(cookies[i].getName())){
                String value = cookies[i].getValue();
                String[] values = value.split("&");
                username = values[0];
                password = values[1];
            }
        }
        UserService us = new UserService();
        User user = us.findUser(username, password);
        if(user != null){
            req.getSession().setAttribute("user", user);
        }
        //3、放行
        arg2.doFilter(arg0, arg1);
    }

 三、自动登录  (PS bean的属于性名和数据库里的字段名千万比方一如既往哦 不然会emmm 很无助)

  1. 当用户登陆成功后,判断是否勾选了自行登陆,如果勾选了,就拿用户称和密码持久化存储到cookie
  2. 做一个Filter,对亟待活动登陆的资源开展拦阻

首形容如当登录Servlet中登录成功时将登录的消息保存于cookie里,并安装存活时间

if(null != user){
            String autologin = request.getParameter("autologin");

            Cookie cookie = new Cookie("user", user.getUsername()+"&"+user.getPassword());
            cookie.setPath("/");
            if(autologin != null){// on / null
                cookie.setMaxAge(60*60*24*7);
            }else{
                cookie.setMaxAge(0);
            }
            response.addCookie(cookie);
            request.getSession().setAttribute("user", user);
            request.getRequestDispatcher("/home.jsp").forward(request, response);
        }

 然后装好filter类 记住要于web.xml里面配备  如下 为 doFilter代码

public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        //1、转换对象
        HttpServletRequest req = (HttpServletRequest) arg0;
        //2、处理业务
        Cookie[] cookies = req.getCookies();
        String username = "";
        String password = "";
        for (int i = 0;cookies!=null && i < cookies.length; i++) {
            if("user".equals(cookies[i].getName())){
                String value = cookies[i].getValue();
                String[] values = value.split("&");
                username = values[0];
                password = values[1];
            }
        }
        UserService us = new UserService();
        User user = us.findUser(username, password);
        if(user != null){
            req.getSession().setAttribute("user", user);
        }
        //3、放行
        arg2.doFilter(arg0, arg1);
    }