WEB-04

1.Listener监听器

1.1 监听器的概述

1.1.1 什么是监听器

监听器就是一个实现了特点接口的Java类,这个Java类用于监听另一个Java类的方法调用或者属性的改变。当被监听对象发生上述事件后,监听器某个方法将会立即被执行。

1.1.2 监听器的用途

用来监听其他对象的变化。主要应用在图形化界面开发上。

  • Java中GUI,Android

1.1.3 监听器的术语

  • 事件源:指的是被监听对象(汽车)
  • 监听器:指的是监听的对象(报警器)
  • 事件源和监听器绑定:在汽车上安装报警器
  • 事件:指的是事件源对象的改变(踹了汽车一脚)–主要功能是获得事件源对象

1.2 监听器的入门

1.2.1 监听器的入门程序

在这里插入图片描述

1.2.2 监听器的执行过程

在这里插入图片描述

1.3 Servlet中的监听器

1.3.1 Serlvet中的监听器简介

在Servlet中定义了多种类型的监听器,它们用于监听的事件源分别是ServletContext、HttpSession和ServletRequest这三个域对象。

1.3.2 Servlet中的监听器的分类

  • 一类:监听三个域对象的创建和销毁的监听器(三个)
  • 二类:监听三个域对象的属性变更(属性添加、移除、替换)的监听器(三个)
  • 三类:监听HttpSession中JavaBean的状态改变(钝化、活化、绑定、解除绑定)的监听(两个)

1.4 第一类监听器

监听三个域对象的创建和销毁的监听器]

1.4.1 SerlvetContextListener

####1.4.1.1 SerlvetContextListener的作用

  • 用来监听SerlvetContext域对象的创建和销毁的监听器
1.4.1.2 ServletContext的创建和销毁

SerlvetContext

  • 创建:服务器启动的时候,为每个web应用创建单独的SerlvetContext对象。
  • 销毁:服务器关闭的时候,或者项目从web服务器中移除的时候。
1.4.1.3 ServletContextListener监听器的方法
  • 监听ServletContext对象的创建
    在这里插入图片描述

  • 监听ServletContext对象的销毁
    在这里插入图片描述

1.4.1.4 编写监听器

在这里插入图片描述

1.4.1.5 绑定监听器和事件源

通过配置方式绑定

在web.xml

在这里插入图片描述

1.4.1.6 ServletContextListener企业用途
  • 记载框架的配置文件:
    Spring框架提供了一个核心监听器ContextLoaderListener。

  • 定时任务调度

1.4.2 HttpSessionListener监听器

1.4.2.1 HttpSessionListener监听器的作用

用来监听HttpSession对象的创建和销毁

1.4.2.2 HttpSession创建和销毁
  • 创建:服务器端第一次调用getSession()方法的时候
  • 销毁:
    ① 非正常关闭服务器(正常关闭服务器session会被序列化)
    ② Session过期(默认过期时间30分钟)
    ③ 手动调用session.invalidate()方法
1.4.2.3 HttpSessionListener监听器的方法
  • 监听HttpSession创建
    在这里插入图片描述
  • 监听HttpSession销毁
    在这里插入图片描述
1.4.2.4 编写监听器监听HttpSession对象创建和销毁
1.4.2.5 监听器代码

在这里插入图片描述

1.4.2.6 监听器配置

……

注意:

  • 访问HTML是否创建Session :不会
  • 访问JSP是否创建Session :会
  • 访问Servlet是否创建Session :不会(默认没有调用getSession方法)

1.4.3 ServletRequestListener监听器的

1.4.3.1 ServletRequestListener的作用
  • 用户监听ServletRequest对象的创建和销毁
1.4.3.2 ServletRequest对象的创建和销毁
  • 创建:从客户端向服务器发送一次请求,服务器就会创建request对象。
  • 销毁:服务器对这次请求作出了响应之后,request对象就销毁了。
1.4.3.3 ServletRequestListener监听器的方法

在这里插入图片描述

1.4.3.4 编写监听器监听ServletRequest对象创建和销毁
1.4.3.5 监听器代码

在这里插入图片描述

1.4.3.6 监听器配置

……

注意

  • 访问HTML页面是否创建请求对象 :会
  • 访问JSP页面是否创建请求对象 :会
  • 访问Servlet是否创建请求对象 :会

1.4.4 案例-统计当前在线人数

1.4.4.1 案例分析

在这里插入图片描述

1.4.4.2 代码实现
  • 创建MySerlvetContextListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //在服务器启动的时候初始化一个值为0
        //把这个值存入到ServletContext中
        servletContextEvent.getServletContext().setAttribute("count",0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}
  • 创建MyHttpSessionListener
public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        //在线
        //获得原来的值,进行加一操作
        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId()+"上线了");
        //获得ServletContext中的值
        int count = (int) session.getServletContext().getAttribute("count");
        count++;
        session.getServletContext().setAttribute("count",count);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        //下线
        //获得原来的值,进行减一操作
        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId()+"上线了");
        //获得ServletContext中的值
        int count = (int) session.getServletContext().getAttribute("count");
        count--;
        session.getServletContext().setAttribute("count",count);
    }
}

编辑一个JSP来显示在线人数

<h1>在线人数:${applicationScope.count}</h1>

1.5 第二类监听器

监听三个域对象的属性变更(属性添加、移除、替换)的监听器

1.5.1 ServletContextAttributeListener

  • 监听ServletContext对象中的属性变更(属性添加,移除,替换)的监听器

方法
在这里插入图片描述

1.5.2HttpSessionAttributeListener

  • 监听HttpSession对象中的属性变更的监听器

方法
在这里插入图片描述

1.5.3 ServletRequestAttributeListener

  • 监听ServletRequest对象中的属性变更的监听器

方法
在这里插入图片描述

1.5.4 演示第二类监听器

由于这三个监听器方法都类似,所以选择HttpSessionAttributeListener来进行演示。

在这里插入图片描述
在这里插入图片描述

1.6 第三类监听器

用来监听HttpSession中Java类状态改变的监听器

1.6.1 第三类监听器概述

保存在Session域中的Java类可以有多种状态:
① 绑定到session中;
② 从session中解除绑定;
③ 随session对象持久化到一个存储设备中(钝化);
④ 随session对象从一个存储设备中恢复(活化)。

Servlet规范中定义了两个特殊的监听接口来帮助Java类来了解自己在Session域中的状态:

  • HttpSessionBindingListener 接口
  • HttpSessionActivationListener 接口

实现这两个接口的类不需要再web.xml中进行配置

1.6.1.1 HttpSessionBindingListener监听器

监听Java类在HttpSession中的绑定和解除绑定的状态的监听器

在这里插入图片描述

测试代码:
在这里插入图片描述

1.6.1.2 HttpSessionActivationListener监听器

监听HttpSession中Java类的钝化和活化监听器。
在这里插入图片描述
在这里插入图片描述

  • 配置完成session的序列化和反序列化
    Context标签可以配置在:
    Tomcat/conf/context.xml:所有tomcat下虚拟主机和虚拟目录下的工程都会序列化session
    Tomcat/conf/Catalina/localhost/context.xml:只有localhost这个虚拟主机下的所有项目会序列化session
    工程/META-INF/context.xml:只有当前工程才会序列化session

注意:
在idea创建web项目并不会直接创建META-INF文件夹
① 打开Project Structure
② 选择Facets,然后Add Application Server specific descriptor
③ 在打开的选择框中选择Tomcat即可

2.Filter过滤器

2.1 Filter的概述

2.1.1 什么是Filter

Filter称为过滤器,它是Servlet技术中最实用的技术,web开发人员通过Filter技术,对web服务器所管理的资源(JSP,Servlet,静态图片或静态html文件)进行拦截,从而实现一些特殊的功能。
Filter就是过滤从客户端向服务器发送的请求。

2.1.2 为什么学习过滤器

在这里插入图片描述

2.2 Filter的入门

2.2.1 第一步:编写一个类实现Filter接口

在这里插入图片描述

2.2.2 第二步:对过滤器进行配置

在这里插入图片描述

2.3 FilterChain对象的概述

2.3.1 FilterChain对象的概述

FilterChain过滤器链:在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为是一个过滤器链。
Web服务器根据Filter在web.xml文件中的注册顺序(mapping的配置顺序)决定先调用那个Filter。依次调用后面的过滤器,如果没有下一个过滤器,调用目标资源。

在这里插入图片描述

2.4 Filter的生命周期

2.4.1 Filter的生命周期的描述

Filter的创建和销毁是由web服务器负责。Web应用程序启动的时候,web服务器创建Filter的实例对象。并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)。

每次filter进行拦截的时候,都会执行doFilter的方法。

当服务器关闭的时候,应用从服务器中移除的时候,服务器会销毁Filter对象。

2.5 FilterConfig对象

2.5.1 FilterConfig的概述

2.5.1.1 FilterConfig的作用

用来获得Filter的相关的配置的对象。

2.5.1.2 FilterConfig对象的API

在这里插入图片描述

代码演示
在这里插入图片描述

2.6 过滤器的相关配置

2.6.1 <url-pattern>的配置

  • 完全路径匹配 :以/开始 比如/aaa /aaa/bbb
  • 目录匹配 :以/开始 以结束 比如/ /aaa/* /aaa/bbb/*
  • 扩展名匹配 :不能以/开始 以开始 比如.jsp *.do *.action

2.6.2 <servlet-name>的配置

专门以Servlet的配置的名称拦截Servlet

2.6.3 <dispatcher>的配置

  • 默认的情况下过滤器会拦截请求。如果进行转发(需要拦截这次转发)。

dispatcher的取值

  • REQUEST :默认值。默认过滤器拦截的就是请求。
  • FORWARD:转发。
  • INCLUDE :页面包含的时候进行拦截
  • ERROR :页面出现全局错误页面跳转的时候进行拦截’

2.7 案例:权限验证过滤器

2.7.1 案例需求

现在一个网站上需要有登录的功能,在登录成功后,重定向到后台的成功页面(后台的页面有很多)。如果现在没有登录直接在地址栏上输入后台页面地址。
编写一个过滤器:可以对没有登录的用户进行拦截。(没有登录,回到登录页面。如果已经登录,放行。)

2.7.2 案例登录功能

与之前大同小异,唯一一处不同的就是在登录的Servlet中,为了防止因项目名称变更导致的页面重定向失败,使用了

在这里插入图片描述
替代了

在这里插入图片描述
在login.jsp页面同样如此
在这里插入图片描述

2.7.3 案例权限过滤器

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//判断用户是否已经登录。如果已经登陆,放行。如果没有登陆回到登陆页面
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        User existUser = (User) req.getSession().getAttribute("existUser");
        //判断:
        if(existUser == null ){
            //没有登录
            req.setAttribute("msg","您还没有登录!没有权限访问");
            req.getRequestDispatcher("/login.jsp").forward(req,servletResponse);
        }else {
            //已经登陆:
            filterChain.doFilter(req, servletResponse);
        }
    }

在这里插入图片描述
<url-pattern>设置成了jsp文件夹下的所有文件,这样如果用户不登录就进入到这些修改页面就都会跳转回登录页面

2.8 案例:通用的字符集编码过滤器

2.8.1 案例分析

网站,需要向后台提交中文的数据(有可能是GET也有可能是POST)。中文处理根据不同的请求方式,处理的方式也是不一样的。
需要调用request.getParameter();方法接收数据,但是这个时候无论是get还是post接收的数据都是存在乱码。现在调用request.getParameter()方法无论是get还是post请求提交的中文,都没有乱码。

2.8.2 增强request类的getParameter方法

通过上面的分析,现在增强request的getParameter的方法。增强的过程要写在过滤器中。

如何增强一个类中的方法?
① 继承

  • 必须要能够控制这个类的构造。

② 装饰者

  • 被增强的类和增强的类需要实现相同的接口。
  • 在增强的类中获得被增强的类的引用。
  • 缺点:接口中的方法过多,重写很多其他的方法。

③ 动态代理

  • 类需要实现接口。

2.8.3 案例代码

新建 submit.jsp

<body>
<form action="${pageContext.request.contextPath}/SubmitServlet" method="post">
    姓名:<input type="text" name="username"><br>
    <input type="submit" name="提交">
</form>
<form action="${pageContext.request.contextPath}/SubmitServlet" method="get">
    姓名:<input type="text" name="username"><br>
    <input type="submit" name="提交">
</form>
</body>

新建一个过滤器,记得去web.xml中配置他

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //在过滤器中增强request对象,并将增强后的request对象传递给Servlet。
        MyHttpServletRequest myHttpServletRequest = new MyHttpServletRequest(request);
        filterChain.doFilter(myHttpServletRequest,servletResponse);
    }

新建一个增强的类,来继承HttpServletRequest的包装类HttpServletRequestWrapper,然后重写增强其中的request.getParameter()方法

public class MyHttpServletRequest extends HttpServletRequestWrapper {
    private HttpServletRequest request;

    public MyHttpServletRequest(HttpServletRequest request) {
        super(request);
        this.request = request;
    }

    //增强request.getParameter()方法

    @Override
    public String getParameter(String name) {
        //获得请求方式
        String method = request.getMethod();
        //根据是get还是post请求进行不同方式的乱码处理
        if("GET".equalsIgnoreCase(method)){
            //GET方式的请求
            String parameter = super.getParameter(name);
            try {
                parameter = new String(parameter.getBytes("UTF-8"),"UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return parameter;
        }else if("POST".equalsIgnoreCase(method)){
            //POST方式的请求
            try {
                request.setCharacterEncoding("UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return super.getParameter(name);
    }

在写该程序时,由于get方法得到的参数本身就是UTF-8编码的,我按照教程使用ISO-8859-1,反而乱码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值