1. 过滤器介绍

    1. 什么是过滤器

生活中的例子:

滤水器,口罩,杯子上滤网,渔网

生活中的过滤器:留下我们想要的,排除,我们不想要的。

高考: 只有分数够高的同学才能进入理想的大学。有一部分同学被拦截在大学之外。(起到拦截的作用)

传智播客: 一开始大家都是小白,进入传智播客学习,经历了4个月的学习,毕业之后,具有了一定(月薪10000左右)的编码能力。

(对每一个经过的学员,都增强了学员的编码能力,起到了增强的作用)

JavaWeb中的过滤器的概念: 对请求和响应进行拦截或者增强的对象,就是过滤器。

JavaWeb中的过滤器是什么呢?

Filter接口:功能——对请求和响应进行增强,或者进行拦截。

  1. JavaWEB中的过滤器运行图解

  1. Filter的快速入门(重点:必须掌握)

  1. Filter定义以及创建步骤介绍

package cn.itcast.filter;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;/*** @author wjn* 总结:过滤器书写步骤* 第一:创建类实现接口——DemoFilter implements Filter* 第二:过滤任务写在doFilter方法中* 第三:web.xml中配置*/public class  @Override//销毁的方法public void destroy() {}@Override//执行过滤的方法public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {System.out.println("DemoFilter.....doFilter....");}@Override//初始化的方法public void init(FilterConfig arg0) throws ServletException {}} 

Filter 是在 Web 应用程序的部署描述符中配置的——过滤器创建好之后,需要在web.xml中做配置

  1. 在web.xml文件中配置过滤器

     <filter><filter-name>DemoFilter</filter-name><filter-class>cn.itcast.filter.DemoFilter</filter-class></filter><filter-mapping><filter-name>DemoFilter</filter-name><url-pattern>/1.txt</url-pattern></filter-mapping> 

    1. Filter拦截操作效果

    1. 过滤器放行的对象:FilterChain功能介绍

    FilterChain的doFilter方法

    代码实现

    过滤器放行执行过程:

    1. Filter生命周期

    为什么要学习生命周期?

    (servlet,只有知道servlet是在什么时候创建和什么时候销毁,才能知道,我在什么时候可以使用servlet)

    我需要知道servlet存活的时间,才能正确的使用servlet对象。

    对于过滤器,我们同样要知道,过滤器什么时候被创建,什么时候被销毁,我们才能正确的使用过滤器。

    1. Filter生命周期

    回顾servlet的生命周期:

    创建: 第一次被访问的时候

    销毁: 服务器关闭的时候,或者当前项目从服务器中移除

    回顾session的生命周期:

    创建: 第一次调用getsession方法

    销毁: 服务器非正常关闭,超过生存时间,调用销毁(自杀)的方法

    Filter:

    创建:在服务器启动的时候

    服务器启动截图:

    销毁: 在服务器关闭的时候,过滤器销毁。

    服务器关闭截图:

    1. FilterConfig介绍

    servletConfig对象:获取servlet相关的配置信息。

    FilterConfig定义:获取filter相关的配置信息。

    API介绍:

    API代码演示:

    1)设置过滤器初始化参数

    2)通过filterconfig对象来获取参数

    参数配置:

    效果演示:

    同学提问:filter是不是单例的?

    1. 类比servlet,我们通过什么来测试,servlet是单例的?

    测试单例的思路:

    1. 设置一个成员变量在过滤器中
    2. 发送两次请求,都去操作成员变量
    3. 如果前一次请求操作的结果,影响后一次请求获取到的成员变量,那么filter就是单例的,反之,不是单例。
    1. Filter配置详解(web.xml中的配置)

      1. 关于url-pattern配置

    过滤器如何匹配请求的路径?

    回顾servlet的url-pattern:

    全路径匹配——

    地址栏:localhost:8080/项目根路径/资源路径 localhost:8080/itcast-filter2/1.txt

    通配符的匹配——

    地址栏:localhost:8080/项目根路径/abc/*

    以上两种匹配方式,配置路径的时候必须以"/"开头

    后缀名匹配——/路径/*.do: *.do *.txt *.action

    地址栏:localhost:8080/项目根路径/*.txt

    后缀名匹配方式,配置路径的时候不能以"/"开头

    Filter的url-pattern配置与servlet一致。

    过滤器的执行顺序?

    测试方式:

    1. 两个过滤器,拦截同一个请求
    2. 调整两个过滤器的配置,再来看执行的顺序

    总结:

    过滤器执行的顺序是按照,web.xml中filter-mapping标签的书写顺序执行(从上往下执行)

    1. 关于servlet-name配置

    什么是servlet-name配置?

    定义:针对指定的servlet进行拦截或者增强操作的配置

    Servlet:

    package cn.itcast.web;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class DemoServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("DemoServlet.....执行.......");}public void doPost(HttpServletRequest request, HttpServletResponse             throws ServletException, IOException {doGet(request, response);}} 

    Filter:

    package cn.itcast.filter;import java.io.IOException;import java.util.Enumeration;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;/*** @author wjn* 1:定义一个类,实现javax.servlet.Filter;* 2:要进行拦截或者增强的代码,要写在doFilter方法中* 3:在web.xml中做配置*/public class  @Override//初始化的方法public void init(FilterConfig config) throws ServletException {System.out.println("MyFilter....init....");//获取过滤器名称//选中要输出的内容,按住alt,点击两次右斜线
    System.out.println("FilterName:"+config.getFilterName());//获取指定的初始化参数
    String plane = config.getInitParameter("plane");System.out.println("plane:"+plane);String train = config.getInitParameter("train");System.out.println("train:"+train);//获取所有初始化参数的名称
    Enumeration<String> enumeration = config.getInitParameterNames();while(enumeration.hasMoreElements()){System.out.println(enumeration.nextElement());}}@Override//执行过滤任务的方法public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("MyFilter.....doFilter.....");//chain:是放行请求和响应的对象
    chain.doFilter(request, response);}@Override//销毁的方法public void destroy() {System.out.println("MyFilter....destroy....");}} 

    Web.xml配置:

    怎么想公司里的老司机请教:

    1. 我现在在做一个什么功能。
    2. 现在出现了什么状况(报错,页面显示,什么都没有发生)
    3. 我预期的效果是什么(我的思路是什么)
    1. Filter案例--自动登录(重点:必须掌握)

    1. 分析

    自动登陆的功能需求?

    用户懒,不想输入用户名和密码,希望,访问网站,直接自动登陆

    用户的使用场景:

    用户点击网站,访问项目根路径的时候,启动自动登陆

    实现思路:

    1. 用户在第一次登陆网站,保存用户名和密码(使用Cookie技术)
    2. 第二次访问网站,先访问根路径,启动自动登陆的功能(使用过滤器技术,在请求到达项目根路径之前完成自动登陆)

    画图分析:

    工作的时候,自动登陆功能,设置一定要慎重。

    人人网,微博,论坛,贴吧,可以设置自动登录

    银行,企业内网,支付系统,安全系统(国家网络应用,交通信号灯等),慎重选择制作自动登陆

    自动登陆功能,本身就是不安全。

    数据保存在cookie中,都是保存在用户的个人电脑中。

    提供一个用户选择自动登录的选项,修改页面

    1. LoginServlet实现

    package cn.itcast.web;import java.io.IOException;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.itcast.domain.User;import cn.itcast.service.UserService;import cn.itcast.service.impl.UserServiceImpl;public class LoginServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("utf-8");//第一步:接受参数
    String username = request.getParameter("username");String pwd = request.getParameter("pwd");//第二步:调用service方法登录用户
    UserService userService = new UserServiceImpl();User loginUser = userService.login(username ,pwd);//第三步:接收返回值,根据不同返回值不同处理(User == null != null)if(loginUser == null){request.setAttribute("msg", "用户名或者密码错误");request.getRequestDispatcher("/login.jsp").forward(request, response);return;}//登录成功//需求:在登录页面显示用户名/** 第一步:登录成功之后,先记住用户名,通过cookie技术,通过response对象将cookie发送给浏览器** 第二步:在登录页面解析cookie,使用EL表达式的内置对象(cookie),再使用javascript进行解码* *///=================================自动登录修改=========================
    String remember = request.getParameter("remember");if("on".equals(remember)){//表示用户需要记住用户名和密码自动登录
    Cookie c = new Cookie("username", URLEncoder.encode(loginUser.getName(), "utf-8"));c.setMaxAge(60*60*24*7);c.setPath("/");response.addCookie(c);Cookie c2 = new Cookie("password",pwd );c2.setMaxAge(60*60*24*7);c2.setPath("/");response.addCookie(c2);}else{//用户不需要自动登录
    Cookie c = new Cookie("username","");c.setMaxAge(0);c.setPath("/");response.addCookie(c);Cookie c2 = new Cookie("password","" );c2.setMaxAge(0);c2.setPath("/");response.addCookie(c2);}//=================================自动登录修改=========================
    request.getSession().setAttribute("loginUser", loginUser);//response.sendRedirect(request.getContextPath()+"/findAllContact");//response.sendRedirect(request.getContextPath()+"/queryPage?pageNum=1");
    response.sendRedirect(request.getContextPath()+"/queryPage2?pageNum=1");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

    1. 过滤器实现

      package cn.itcast.filter;import java.io.IOException;import java.net.URLDecoder;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.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.itcast.domain.User;import cn.itcast.service.UserService;import cn.itcast.service.impl.UserServiceImpl;publicclass AutologinFilter implements Filter{@Overridepublicvoid destroy() {}@Overridepublicvoid doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//第一步: 获取数据 (cookie username password)//HttpServletRequest?
    HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;Cookie[] cookies = req.getCookies();if(cookies == null){res.sendRedirect(req.getContextPath()+"/login.jsp");return;}else{//将cookie中的username和password
    String username = "";String password = "";for (Cookie cookie : cookies) {if("username".equals(cookie.getName())){username = URLDecoder.decode(cookie.getValue(), "utf-8") ;}if("password".equals(cookie.getName())){password = cookie.getValue();}}if(username.equals("") || password.equals("")){res.sendRedirect(req.getContextPath()+"/login.jsp");return;}else{//第二步:调用方法(UserService.login())
    UserService userService = new UserServiceImpl();User loginUser = userService.login(username, password);//第三步:根局不同返回值,不同处理if(loginUser == null){res.sendRedirect(req.getContextPath()+"/login.jsp");return;}else{req.getSession().setAttribute("loginUser", loginUser);res.sendRedirect(req.getContextPath()+"/queryPage2?pageNum=1");return;}}}}@Overridepublicvoid init(FilterConfig arg0) throws ServletException {}} 

    web.xml配置:

    <!-- =======================过滤器配置=============================== --><filter><filter-name>AutologinFilter</filter-name><filter-class>cn.itcast.filter.AutologinFilter</filter-class></filter><filter-mapping><filter-name>AutologinFilter</filter-name><!-- 因配置文件中默认的主页index.jsp,所访问根路径的时候,默认会跳转到主页上,所以,我们配置 url-pattern使用index.jsp --><url-pattern>/index.jsp</url-pattern></filter-mapping><!-- =======================过滤器配置=============================== --> 

    1. 案例--解决day14_Contact项目中乱码

    需求:请求参数在每一个servlet中单独中文乱码处理,代码重复

    优化的思路,使用一个过滤器,在请求到达servlet之前,先对象request对象进行设置编码

    要对所有的请求都要进行设置编码,都要拦截,进行增强,url-pattern:/*

    过滤器代码:

    package cn.itcast.filter;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.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class EncodingFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// 强制转换request response
    HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;//处理响应乱码
    res.setContentType("text/html;charset=utf-8");//处理POST请求乱码
    req.setCharacterEncoding("utf-8");chain.doFilter(req, res);}@Overridepublic void destroy() {}}

    Web.xml配置:

    补充(装饰(包装)设计模式口诀):

    1. 定义一个类,实现被装饰对象的接口
    2. 定义一个成员变量,记住被装饰对象的引用
    3. 定义构造方法,传入被装饰对象的实例
    4. 改写要修改的方法
    5. 不需要改写的方法,调用被装饰对象的原来的方法

    补充:什么时候使用装饰设计模式

    当我们需要对一个类进行增强的时候,增强后的类不再当前类的范畴(animal类型 cat dog都属于动物类型中可以使用继承,电子狗,不属于动物范围,所以选择使用包装设计模式 )中

    复杂过滤器实现:

    package cn.itcast.filter;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.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.itcast.domain.MyRequest;public class EncodingFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// 强制转换request response
    HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;//处理响应乱码
    res.setContentType("text/html;charset=utf-8");//自定义一个request对象:MyRequest,对服务器原来的request进行增强,使用装饰设计模式//要增强原来的request对象,必须先获取到原来的request对象
    MyRequest myrequest = new MyRequest(req);//注意:放行的时候应该,传入增强后的request对象
    chain.doFilter(myrequest, res);}@Overridepublic void destroy() {}} 

    自定义增强类:

    package cn.itcast.domain;import java.io.UnsupportedEncodingException;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;//第一问题:HttpServletRequestWrapper他是什么?//HttpServletRequestWrapper:它实现了HttpServletRequest接口,继承当前对象之后,也是HttpServletRequest接口的实现类//第一问题:增强request,可以直接实现接口,为什么要继承HttpServletRequestWrapper?//因为HttpServletRequestWrapper,已经实现了接口的方法,我们只需继承就可以使用,//如果需要对某些方法增强,只需要修改部分方法即可,其他,调用父类的方法就完成了/*** 补充(装饰(包装)设计模式心法):1)    定义一个类,实现被装饰对象的接口2)    定义一个成员变量,记住被装饰对象的引用3)    定义构造方法,传入被装饰对象的实例4)    改写要修改的方法5)    不需要改写的方法,调用被装饰对象的原来的方法* *///1)    定义一个类,实现被装饰对象的接口public class MyRequest extends HttpServletRequestWrapper{//2)    定义一个成员变量,记住被装饰对象的引用private HttpServletRequest request = null;//3)    定义构造方法,传入被装饰对象的实例//设置一个标记,用来防止,编码多次运行,要保证get方式编码,只运行一次private boolean flag = false;public MyRequest(HttpServletRequest request) {super(request);this.request = request;}//4)    改写要修改的方法//所有获取参数的方法,都需要改写
    @Overridepublic Map<String, String[]> getParameterMap() {//先判断请求的方式——每一次请求,只会有一种请求方式post get
    String method = this.request.getMethod();if("post".equalsIgnoreCase(method)){//post请求方式try {this.request.setCharacterEncoding("utf-8");return this.request.getParameterMap();} catch (UnsupportedEncodingException e) {e.printStackTrace();return super.getParameterMap();}}else if("get".equalsIgnoreCase(method)){//先获取所有的数
    Map<String, String[]> map = this.request.getParameterMap();if(map == null){return super.getParameterMap();}//如果flag是false,说明没有执行过,执行中文乱码处理//如果flag是true,说明执行过乱码处理,不再重复if(flag){return map;}//遍历循环map集合,将每一个数据进行中文乱码处理//循环map集合的时候,先获取所有key的Set集合,然后,根据key,获取value值//当前循环结束,map集合中所有数据处理完成for (String key : map.keySet()) {//获取的数据是String数组
    String[] value = map.get(key);//当前for循环结束之后,value中的数据全部处理完成for(int i = 0 ;i< value.length ;i++){try {String temp = new String(value[i].getBytes("iso-8859-1"),"utf-8");//再存入原来的位置
    value[i] = temp;} catch (UnsupportedEncodingException e) {e.printStackTrace();//这里还在继续循环,所以不能return结束
    }}}//循环结束,标记设置为true
    flag = true;return map;}else{return super.getParameterMap();}}@Overridepublic String[] getParameterValues(String name) {//先获取所有的数据,map
    Map<String, String[]> map = this.getParameterMap();if(map == null){return super.getParameterValues(name);}//获取map集合中指定数据,根据name指定,相当于key
    String[] values = map.get(name);return values;}@Overridepublic String getParameter(String name) {//获取指定请求参数的数组
    String[] values = this.getParameterValues(name);if(values == null){return super.getParameter(name);}//如果有数据,返回,数组中的第一个数据return values[0];}} 

    注意:最后还有去掉原来设置编码的代码。

    1. 监听器介绍

  2. 什么是监听器

    生活中的例子:

    银行的自动门,班导

    监听器:监听事件源,根据事件源上发生事件,做出相应的处理。

  3. 监听机制相关概念

    事件源:发生事件的源头,监听器需要监听的对象。

    事件:事件源上发生的动作,监听器监听的内容。

    监听器:负责监听事件源的对象。

  4. web监听器介绍

  5. javaweb监听器介绍

    JavaWEB中的监听器主要监听JavaWEB中的request、session、ServletContext对象的各种变化。

    主要监听的任务:

    1. 监听request、ServletContext 、session对象的创建和销毁 (练习)
      1. ServletRequestListener、ServletContextListener、HttpSessionListener
    2. 监听request、session、ServletContext 对象存放的数据变化情况(练习)
      1. ServletContextAttributeListener 、HttpSessionAttributeListener 、ServletRequestAttributeListener
    3. 监听session中保存的JavaBean的状态
      1. HttpSessionBindingListener
  6. javaweb监听器创建步骤(示例:ServletRequestListener)

  7. 需要定义一个类实现对应的监听器接口

    ServletRequestListener定义(API截图):

    代码演示:

    package cn.itcast.listener;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;public class  @Override//监听request对象销毁的方法public void requestDestroyed(ServletRequestEvent sre) {System.out.println("MyServletRequestListener.....requestDestroyed....");}@Override//监听request对象初始化的方法public void requestInitialized(ServletRequestEvent sre) {System.out.println("MyServletRequestListener.....requestInitialized....");}} 

  8. 配置监听器对象

    注意:当服务器加载项目的时候,会读取web.xml文件中listener标签,那么服务器会自动创建监听器对象,并且自动调用其方法

    监听器的小结:

    1. 创建一个类,实现监听器接口
    2. 在监听器对象的方法中,书写相关的代码
    3. 在web.xml中配置当前监听器。
  9. ServletContext创建销毁监听(ServletContextListener)

    ServletContextListener定义(API截图):

    代码演示:

    package cn.itcast.listener;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;public class  @Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("MyServletContextListener.....contextInitialized....");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("MyServletContextListener.....contextDestroyed....");}} 

    监听器配置:

     <listener><listener-class>cn.itcast.listener.MyServletContextListener</listener-class></listener> 

    监听servletcontext对象初始化截图:

    监听servletcontext对象销毁截图:

  10. 案例:定时任务演示

    需求:项目启动时,获取服务器时间(new Date()),每一秒钟更新一次,打印在控制台

    思路:

    1)监控项目的启动(使用ServletContextListener来监听ServletContext对象的初始化)

    1. 获取服务器时间:new Date();
    2. 每一秒更新一次:定时器Timer

    4)给定时器设置定时任务

    Timer:定时器

    timeTask:定时器的任务(类)

    firstTime:从什么时候开始执行,立即执行设置为:0

    period :间隔多少时间重复执行,毫秒值,1秒=1000毫秒

    TimerTask:定时器的任务(类)

    Run方法中应该写我们的定时任务:每一秒钟更新一次时间,打印在控制台上

    代码实现:

    package cn.itcast.listener;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;/*** @author wjn* 1)    创建一个类,实现监听器接口2)    在监听器对象的方法中,书写相关的代码3)    在web.xml中配置当前监听器。*/public class MyServletContextListener implements ServletContextListener{@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("MyServletContextListener....contextInitialized...");//监控项目的启动(使用ServletContextListener来监听ServletContext对象的初始化)//2)    获取服务器时间:new Date();//3)    每一秒更新一次:定时器Timer//4) 给定时器设置定时任务//获取定时器
    Timer timer = new Timer();//调用定时器的设置定时任务的方法//firstTime 0:立即执行//period:间隔多长时间执行一次,1000
    timer.schedule(new TimerTask() {@Overridepublic void run() {//在run方法中,书写,要执行的任务//过时的方法一般不推荐使用,但是,过时的方法,jdk不会删除它的效果。//当前显示时间,可以使用服务器中的时间——java代码,new Date();//当前显示时间——javascript代码,new Date();//javascript代码,是在浏览器运行,客户端的时间,一般是不使用客户端的时间//业务:整点秒杀//获取的是服务器时间,用户,是没有办法控制//获取客户端时间,时间有客户控制,时间是不对的//一般尊循的原则,只要可以控制在服务器的,绝对不给客户端
    System.out.println(new Date().toLocaleString());}}, 0, 1000);}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("MyServletContextListener....contextDestroyed...");}} 

    效果:

    1. HttpSessionListener对象监听session的创建与销毁监听

    HttpSessionListener定义(API截图):

    代码演示:

    package cn.itcast.listener;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class  @Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("MyHttpSessionListener....sessionCreated....");}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("MyHttpSessionListener....sessionDestroyed....");}} 

    配置文件:

    <listener><listener-class>cn.itcast.listener.MyHttpSessionListener</listener-class></listener> 

    Invalidate.jsp页面代码:

     <%session.setAttribute("user", new User());session.removeAttribute("user");%>

    效果截图:

  11. 统计在线人数

    用户积累:优惠,折扣,广告,扫码关注,想所有QQ用推送一条消息,给所有支付宝用户发送消息。

    第三方登录,QQ账号,微博账号,微信账号,优酷账号,支付宝账号,银行账户,百度账号

    1. 用户体验非常好
    2. 创业公司,除了积累用户以外,还获取了用户的QQ或者支付宝,或者微信,可以使用现成推广渠道,再次推广自己应用

    需求:统计当前访问网站的人数有多少人?

    什么时候我们可以知道用户访问了网站?

    只要用户访问了我们的网站,session一定会创建。只要用户离开,点退出,session就销毁。

    思路:

    只要判断session创建,在线人数就加一

    只要判断session销毁,在线人数就减一

    在线人数的数据,要存在哪里?

    ServletContext对象中,所有应用程序范围都可以获取,所有访问当前网站的用户,都应该可以看到在线人数

    总思路:

    1)先在servletContext中初始化在线人数参数;当前项目初始化的时候,将在线人数初始化:0人。

    2)在监听器中只要判断session创建,在线人数就加一

    3)在监听器中只要判断session销毁,在线人数就减一

    代码实现:

    监听器代码:

    package cn.itcast.listener;import javax.servlet.ServletContext;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("MyHttpSessionListener....sessionCreated....");// 在监听器中只要判断session创建,在线人数就加一
    ServletContext context = se.getSession().getServletContext();// 获取里面的在线人数
    Integer onlineNum = (Integer) context.getAttribute("onlineNum");onlineNum = onlineNum + 1;context.setAttribute("onlineNum", onlineNum);}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("MyHttpSessionListener....sessionDestroyed....");// 在监听器中只要判断session销毁,在线人数就减去一
    ServletContext context = se.getSession().getServletContext();// 获取里面的在线人数
    Integer onlineNum = (Integer) context.getAttribute("onlineNum");onlineNum = onlineNum - 1;context.setAttribute("onlineNum", onlineNum);}} 

    index.jsp显示在线人数,显示退出链接:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body>itcast-filter2项目主页<br>当前在线人数:${onlineNum }<a href="${pageContext.request.contextPath }/validate.jsp">退出</a></body></html> 

    页面效果:

  12. 属性变化的监听

  13. 属性监听器介绍

    主要是监听使用setAttribute、removeAttribute方法。

    ServletContextAttributeListener 专门用于监听ServletContext对象中的属性的变化情况

    HttpSessionAttributeListener 专门用于监听session对象中的属性的变化情况

    ServletRequestAttributeListener 专门用于监听request对象中的属性的变化情况

    它们中的的监听 添加 、删除 、 修改的方法名称全部一致:

    代码演示:

    Jsp:

    <%//添加数据
    session.setAttribute("addr", 111);//替换数据
    session.setAttribute("addr", 222);//删除数据
    session.removeAttribute("addr");%> 

    监听器:

    package cn.itcast.listener;import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent;public class  @Overridepublic void attributeAdded(HttpSessionBindingEvent se) {System.out.println("MyHttpSessionAttributeListener....attributeAdded...");}@Overridepublic void attributeRemoved(HttpSessionBindingEvent se) {System.out.println("MyHttpSessionAttributeListener....attributeRemoved...");}@Overridepublic void attributeReplaced(HttpSessionBindingEvent se) {System.out.println("MyHttpSessionAttributeListener....attributeReplaced...");}} 

    配置文件:

    <listener><listener-class>cn.itcast.listener.MyHttpSessionAttributeListener</listener-class></listener> 

  14. Bean监听演示

    1. Session中的bean监听

    当我们给Session中保存一个Java对象的时候,或者把Java对象从Session中移除的时候会触发专门用来监听Session中对象变化的监听器中的方法。拥有这个方法的对象——HttpSessionBindingListener接口

    属性监听和bean监听的区别:

    属性监听:是对三个容器中的任何属性(包括对象和不是对象的数据,基本类型数据)的变化,进行监听

    Bean监听:它只监听javabean对象往session中保存和session中移出的过程。

    由于HttpSessionBindingListener是用来监听某个JavaBean对象的绑定和解绑的,所以这个监听器的实现类必须是被操作的JavaBean(HttpSessionBindingListener不需要再web.xml中配置)

    javaBean:

    package cn.itcast.domain;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;public class User implements HttpSessionBindingListener{private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User [age=" + age + ", name=" + name + "]";}@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("User....valueBound...");}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("User....valueUnbound...");}} 

    JSP:

  15. <%

    session.setAttribute("user", new User());

    session.removeAttribute("user");

    %>

     <%session.setAttribute("user", new User());session.removeAttribute("user");%> 

    效果:

    Bean监听需求:

    在线人数,根据session创建和销毁,来做人数的增减。

    在线会员统计:

    1. User类实现bean监听接口
    2. 每次监听到loginUser对象被绑定到session中的时候,会员人数加一
    3. 每次监听到loginUser对象被解绑的时候,会员人数减一
    1. 作业:

    1. 自动登录过滤器(40点积分)
    2. 定时任务(20点积分)
    3. 统计在线任务(进度20点积分)
    4. 全站乱码过滤器简单版(20点积分)
    5. 全站乱码过滤器复杂版(50点积分)

转载于:https://www.cnblogs.com/x-ll123/p/9410651.html

JavaWEB过滤器和监听器技术相关推荐

  1. struts2 javaweb 过滤器、监听器 拦截器 原理

    转: 过滤器.监听器 拦截器 过滤器 创建一个 Filter 只需两个步骤: (1)创建 Filter 处理类: (2)在 web.xml 文件中配置 Filter . 创建 Filter 必须实现 ...

  2. 2019尚硅谷大数据Javaweb篇三 Ajax、JSTL、会话技术、过滤器、监听器、xml、json

    2019尚硅谷大数据 Javaweb篇三Ajax.JSTL.会话技术.过滤器.监听器 tags: 大数据 2019尚学堂 categories: Ajax异步请求 JSTL中的if和forEach 会 ...

  3. JavaWeb(二):Cookie、Session、JSP、过滤器和监听器、JDBC

    JavaWeb-2 学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV12J411M7Sj 学习资料笔记:CSDN – https://blog.c ...

  4. javaweb(11) Listener监听器与Filter过滤器

    javaweb(11) Listener监听器与Filter过滤器 Listener监听器 什么是Listener监听器 Listener 监听器它是 JavaWeb 的三大组件之一.JavaWeb ...

  5. JavaWeb加强之JSON、jQuery、Ajax、Java正则表达式、过滤器、监听器、模板引擎FreeMarker

    过滤器.监听器,以及JSON.Ajax和正则表达式等开发必备技能,并学习文件上传和验证码等功能开发. 2.4.1 JSON基础 JSON的基础语法,以及流行JSON框架FastJSON的使用. 内容: ...

  6. 【JavaWeb】基于 JSP、EL表达式实现登录,并使用过滤器与监听器

    文章目录 任务概述 具体需求 涉及知识点 任务过程 思路及代码实现 一. 工具包 properties配置文件 DBUtils.java 二. 创建数据库 三. 对象 User.java 四. 创建登 ...

  7. 【转载】Spring Boot 过滤器、监听器、拦截器的使用

    关注"Java后端技术全栈" 回复"面试"获取全套大厂面试资料 在开发中用到过滤器.监听器.拦截器的场景非常多,今天就来聊聊这三者在日常开发中是如何使用的. 概 ...

  8. 高手速成 | 过滤器、监听器的创建与配置

    本节讲解过滤器.监听器的创建以及监听事件配置示例. 01.过滤器的创建与配置 [例1]创建过滤器及配置过滤规则. (1) 在Eclipse中新建一个Web项目,取名为Chapt_09.在src目录下, ...

  9. java web.xml 监听器_十:JavaWeb中的监听器(一)

    2.1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域 ...

最新文章

  1. 数据库索引-基本知识
  2. SpringMVC的国际化
  3. HDFS二次开发常见问题
  4. 为什么mysql没有io多路复用_Redis凭啥可以这么快
  5. CCF NOI1136 单词分类
  6. activitygroup
  7. 使用数据驱动进行配对交易:简单交易策略
  8. 如何设计一个小而美的秒杀系统(抢红包)?
  9. 网站使用手机相机_使用“互通相机”把你的iPhone手机变成Mac的心灵之窗!
  10. 推荐 :数据科学家应该避免的5种统计陷阱
  11. 对于CNN卷积神经网络的前向传播和反向传播的理解
  12. vue-video-player视频播放插件
  13. 出门吃饭,手机没电,有感——为什么共享充电宝能活?
  14. Echarts实现横轴数据节点不一致的绘制
  15. 印尼医疗传感器行业调研报告 - 市场现状分析与发展前景预测
  16. iOS 名片识别代码
  17. 集美大学计算机主要学什么,集美大学计算机科学及技术专业课程教学大纲.doc...
  18. 【经验】使用Nginx对kiftd进行反向代理和域名绑定
  19. red110播放_我播放“ Red Dead Redemption 2”以获得风景,而不是射击
  20. Linux下的时间详解【转】

热门文章

  1. 要来了!国内安卓统一推送标准将于3月开启测试
  2. 12月数据库榜单,整体排名稳定如昨,Oracle 分数接连下降
  3. matlab 符号 推倒,【MATLAB】符号数学计算(四):符号表达式操作
  4. pythonwin是什么_winpython是什么
  5. python中head_Python(Head First)学习笔记:二
  6. 基于SSH2做一个24小时订单分析表格
  7. html垂直线性渐变,html5线性渐变
  8. linux c++开发_Linux/Windows下进行C/C++开发的差异
  9. 发送get请求php,如何利用PHP发送GET请求
  10. linux虚拟网卡上网,Linux添加虚拟网卡的多种方法