java web 之 listen 与 filter

一、Listener监听器

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

监听它们的制造与销毁、属性别变化化 以及session绑定javaBean

一、监听机制

  • 事件  正是3个政工
  • 事件源  发生这么些业务的源流
  • 监听器  用于监听内定的事件的目的
  • 登记监听 要想让监听器能够监听到事件发生,必须对其进展注册。

2、Javaweb开辟中常见监听器

贰.1、监听域对象的创制与销毁

  • 监听ServletContext成立与销毁  ServletContextListener
  • 澳门1495娱乐,监听HttpSession创造与销毁  HttpSessionListener
  • 监听HttpServletRequest创设与销毁  ServletRequestListener

二.贰、监听域对象的习性别变化化

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

2.3、监听session绑定javaBean

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

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

三、监听器的快捷入门

至于创造一个监听器的步子

  1. 开创二个类,完毕内定的监听器接口
  2. 重写接口中的方法
  3. 在web.xml文件中对监听器举办登记。
  4. ServletContext对象的创导与销毁

三.一、关于域对象创立与销毁的以身作则

本条指标是在服务器运行时创设的,在服务器关闭时销毁的。

HttpSession对象的始建与销毁

HttpSession session=request.getSession();

Session销毁 的方法

  1. 暗中认可超时  三十多分钟
  2. 关门服务器
  3. invalidate()方法
  4. set马克斯InactiveInterval(int interval) 能够设置超时时间

题材:直接待上访问1个jsp页面时,是或不是会创建session?

会创设,因为我们暗许情况下是能够在jsp页面中央直机关接动用session内置对象的。

HttpServletRequest创立与销毁

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

叁.二、演示了Request域对象中质量变化

在java的监听机制中,它的监听器中的方法都是有参数的,参数正是事件目的,而大家得以经过事件目的直接得到事件源。

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

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

HttpSessionBindingListener 这几个接口是由javaBean实现的,并且不供给在web.xml文件中注册.

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

HttpSessionActivationListener假若javaBean完结了那一个接口,那么当我们健康关闭服务器时,session中的javaBean对象就会被钝化到大家钦定的文件中。

立马一次在起步服务器,因为大家已经将对象写入到文件中,那时就会自动将javaBean对象活化到session中。

大家还须要个context.xml文件来布局钝化时存款和储蓄的文书

在meta-inf目录下开创3个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

壹、监听机制

  • 事件  正是3个作业
  • 事件源  产生那么些工作的源头
  • 监听器  用于监听钦点的事件的对象
  • 挂号监听 要想让监听器能够监听到事件产生,必须对其开始展览注册。

二、Javaweb开发中常见监听器

二.1、监听域对象的创始与销毁

  • 监听ServletContext成立与销毁  ServletContextListener
  • 监听HttpSession创设与销毁  HttpSessionListener
  • 监听HttpServletRequest创设与销毁  ServletRequestListener

2.2、监听域对象的本性别变化化

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

2.3、监听session绑定javaBean

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

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

三、监听器的急迅入门

有关制造1个监听器的步调

  1. 创造四个类,完毕内定的监听器接口
  2. 重写接口中的方法
  3. 在web.xml文件中对监听器实行挂号。
  4. ServletContext对象的创造与销毁

三.一、关于域对象创制与销毁的示范

以此目的是在服务器运行时创制的,在服务器关闭时销毁的。

HttpSession对象的创建与销毁

HttpSession session=request.getSession();

Session销毁 的方法

  1. 暗中认可超时  二十八分钟
  2. 闭馆服务器
  3. invalidate()方法
  4. setMaxInactiveInterval(int interval) 能够设置超时时间

标题:间接待上访问2个jsp页面时,是还是不是会创造session?

会创建,因为大家暗中同意景况下是能够在jsp页面中央直机关接选择session内置对象的。

HttpServletRequest创造与销毁

Request对象是发送请求服务器就会创建它,当响应发生时,request对象就会销毁。

3.2、演示了Request域对象中品质变化

在java的监听机制中,它的监听器中的方法都是有参数的,参数就是事件目的,而我们能够透过事件目标直接拿走事件源。

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

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

HttpSessionBindingListener 这些接口是由javaBean达成的,并且不需求在web.xml文件中注册.

二、javabean对象能够活化或钝化到session中。

HttpSessionActivationListener尽管javaBean完成了这一个接口,那么当我们平常关闭服务器时,session中的javaBean对象就会被钝化到大家钦赐的文书中。

登时三回在运维服务器,因为我们早已将对象写入到文件中,那时就会活动将javaBean对象活化到session中。

小编们还索要个context.xml文件来配置钝化时存款和储蓄的公文

在meta-inf目录下创办2个context.xml文件

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

案例-定期销毁session

一、怎么样能够将每一个创建的session全都保存起来?

大家可以做一个HttpSessionListener,当session对象创建时,就将以此session对象装入到八个聚众中.

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

二、怎么着能够决断session过期了?

在HttpSession中有2个措施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

一、怎么着能够将每2个创办的session全都保存起来?

作者们得以做一个HttpSessionListener,当session对象成立时,就将这么些session对象装入到八个聚集中.

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

贰、如何能够看清session过期了?

在HttpSession中有1个方式public long
getLastAccessedTime()

它能够获得session对象最终动用的时刻,能够应用invalidate方法销毁。

ps(我们地方的操作供给使用任务调度功用.)在java中有1个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中,它肯定是3个多线程的,那么大家的先后对聚集进行了增进,还有移除操作。具体在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
容器为开垦人士提供的对象,它提供了对某1能源的已过滤请求调用链的视图。过滤器使用
FilterChain
调用链中的下二个过滤器,假使调用的过滤器是链中的结尾贰个过滤器,则调用链末尾的能源。

主题材料:怎么着能够产生3个Filter链?

  只要八个Filter对同一个财富举行阻拦就足以形成Filter链

主题素材:如何分明Filter的施行种种?

  由<filter-mapping>来确定

1.2、FilterChain

FilterChain 是 servlet
容器为开荒职员提供的目的,它提供了对某1财富的已过滤请求调用链的视图。过滤器使用
FilterChain
调用链中的下二个过滤器,假诺调用的过滤器是链中的结尾2个过滤器,则调用链末尾的能源。

标题:如何能够形成1个Filter链?

  只要七个Filter对同叁个财富开始展览阻拦就足以形成Filter链

标题:如何鲜明Filter的施行各种?

  由<filter-mapping>来确定

一.3、Filter生命周期

Servlet生命周期:

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

  • 一 当服务器运转,会创设Filter对象,并调用init方法,只调用2次.
  • 2当访问财富时,路线与Filter的阻拦路线相称,会实践Filter中的doFilter方法,这几个格局是确实拦截操作的方法.
  • 三 当服务器关闭时,会调用Filter的destroy方法来展开支毁操作.

一.三、Filter生命周期

Servlet生命周期:

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

  • 1 当服务器运维,会成立Filter对象,并调用init方法,只调用三回.
  • 二当访问财富时,路线与Filter的阻挠路径相称,会实践Filter中的doFilter方法,这些艺术是真的拦截操作的方法.
  • 3 当服务器关闭时,会调用Filter的destroy方法来展开销毁操作.

1.4、FilterConfig

在Filter的init方法上有二个参数,类型便是FilterConfig.

FilterConfig它是Filter的布置对象,它能够实现下列功用

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

澳门1495娱乐 1

主题材料:怎么着在Filter中赢得2个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对象。

澳门1495娱乐 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>

全盘匹配   以”/demo壹”开端,不带有通配符*

目录相配   以”/”开首  以*结束

推而广之名相称  *.xxx  不能写成/*.xxx

1.<url-pattern>

一心相称   以”/demo1”初始,不带有通配符*

目录相配   以”/”初阶  以*结束

强大名相称  *.xxx  无法写成/*.xxx

2.<servlet-name>

它是对点名的servlet名称的servlet进行拦阻的。

2.<servlet-name>

它是对点名的servlet名称的servlet实行阻挠的。

3.<dispatcher>

能够取的值有  REQUEST  FOLANDWARubiconD  ECRUISERROLX570  INCLUDE    根据跳转格局阻碍

它的功效是:当以什么样方式去访问web能源时,进行阻拦操作.

1.REQUEST
当是从浏览器直接待上访问能源,或是重定向到有个别资源时开始展览阻拦形式配置的
它也是私下认可值

2.FOLANDWA奥迪Q伍D 它描述的是呼吁转载的阻止格局布署

三.EHavalROTiguan只要指标能源是由此表明式卓殊处理体制调用时,那么该过滤器将被调用。除了那个之外,过滤器不会被调用。

4.INCLUDE
万一目的财富是经过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除却,该过滤器不会被调用

3.<dispatcher>

能够取的值有  REQUEST  FOXC90WA福睿斯D  ELacrosseROOdyssey  INCLUDE    根据跳转格局阻止

它的意义是:当以什么样点子去拜谒web财富时,举办拦阻操作.

一.REQUEST
当是从浏览器直接待上访问财富,或是重定向到某些资源时进行拦阻情势配置的
它也是默许值

2.FO奥迪Q5WA安德拉D 它描述的是呼吁转载的阻拦情势配置

三.E卡宴RO凯雷德如若指标财富是经过表明式卓殊处理体制调用时,那么该过滤器将被调用。除外,过滤器不会被调用。

4.INCLUDE
1旦目的财富是因而RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除了那么些之外,该过滤器不会被调用

 3、自动登入  (PS bean的属性名和数据Curry的字段名千万要一律哦 不然会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);
    }

 三、自动登6  (PS bean的属性名和数据Curry的字段名千万要壹致哦 不然会emmm 相当惨)

  1. 当用户登录成功后,推断是不是勾选了活动登入,假若勾选了,就将用户名与密码持久化存款和储蓄到cookie
  2. 做2个Filter,对亟待活动登录的财富拓展阻挠

首写要在登入Servlet中登3/5功时把登陆的新闻保存在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);
    }

相关文章