栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Servlet笔记六(Servlet 高级)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Servlet笔记六(Servlet 高级)

文章目录
  • Filter 过滤器
    • Filter 概念
    • Filter 映射
      • 1. 使用通配符 "*" 拦截用户的所有请求
      • 2. 拦截不同方式的访问请求
    • Filter 链
    • FilterConfig 接口
    • 使用 Filter 实现用户自动登录
    • 使用 Filter 实现统一全站编码
  • Listener 监听器
    • Servlet 事件监听器概述
    • 监听域对象的生命周期
    • 监听对象属性变更


Filter 过滤器 Filter 概念

Filter 被称作过滤器,其基本功能就是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理前后实现一些特殊功能。这就好比现实中的污水净化设备,它可以看作一个过滤器,专门用于过滤污水杂志。

当浏览器访问服务器中的目标资源时,会被 Filter 拦截,在 Filter 中进行预处理操作,然后再将请求转发给目标资源。当服务器接收到这个请求后会对其进行响应,在服务器处理响应的过程中,也需要先将响应结果发送给过滤器,在过滤器中对响应结果进行处理后,才会发送给客户端。

其实,Filter 过滤器就是一个实现了 javax.servlet.Filter 接口的类,在 javax.servlet.Filter 接口中定义了 3 个方法。

Filter 接口中的方法

方法声明功能描述
init(FilterConfig filterConfig)init()方法用来初始化过滤器,开发人员可以在 init() 方法中完成与构造方法类似的初始化功能。如果初始化代码中要使用到 FilterConfig 对象,那么,这些初始化代码就只能在 Filter 的 init() 方法中编写,而不能在构造方法中编写
doFilter(SerlvetRequest request, ServletResonse response, FilterChain chain)doFilter() 方法有多个参数,其中,参数 request 和 response 为 Web 服务器或 Filter 链中的上一个 Filter 传递过来的请求和响应对象;参数 chain 代表当前 Filter 链的对象,在当前 Filter 对象中的 doFilter() 方法内部需要调用 FilterChain 对象的 doFilter() 方法,才能把请求交付给 Filter 链中的下一个 Filter 或者目标程序去处理
destroy()destroy() 方法在 Web 服务器卸载 Filter 对象之前被调用,该方法用于释放被 Filter 对象打开的资源,例如关闭数据库和 IO 流

这 3 个方法都是 Filter 的生命周期方法,其中 init() 方法在 Web 应用程序加载的时候调用,destroy() 方法在 Web 应用程序卸载的时候调用,这两个方法都只会被调用一次,而 doFilter() 方法只要有客户端请求时就会被调用,并且 Filter 所有的工作 集中 在 doFilter() 方法中。

MyServlet.java

package com.xxx;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.write("Hello World!");
    }
}

MyFilter

package com.xxx;

import javax.servlet.*;
import java.io.IOException;

// 拦截myservlet, 输出自己的信息
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter is running...");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        response.getWriter().write("Hello MyFilter...");
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter is destroy...");
    }
}

web.xml



    
        myFilter
        com.xxx.MyFilter
    
    
        myFilter
        /myservlet

        super(request);
        this.request = request;
    }

    @Override
    public String getParameter(String name) {

        String value = super.getParameter(name);
        if(value == null) return null;
        String method = super.getMethod();
        String encoding = request.getCharacterEncoding();

        if("iso-8859-1".equalsIgnoreCase(encoding)){
            if("get".equalsIgnoreCase(method.toLowerCase())){
                try{
                    value = new String(value.getBytes("iso-8859-1"), "utf-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return value;
    }
}

4. 配置映射信息



    
        myFilter
        com.xxx.CharacterFilter
    
    
        myFilter
        /*
    

5. 测试结果

get 方式

post 方式

输出(无乱码)

Listener 监听器

在程序开发中,经常需要对某些事件进行监听,如监听鼠标单击事件、监听键盘按下事件等,此时就需要使用监听器,监听器在监听的过程中会涉及几个重要组成部分,具体如下。

  • 事件(Event):用户的一个操作,如单击一个按钮、调用一个方法、创建一个对象等。
  • 事件源:产生事件的对象。
  • 事件监听器(Listener):负责监听发生在事件源上的事件。
  • 事件处理器:监听器的成员方法,当事件发生的时候会触发对应的处理器(成员方法)。

当用户进行一个操作触发事件源上的事件时,就会被事件监听器监听到。当监听器监听到事件发生时,相应的事件处理器就会对发生的事件进行处理。

事件监听器在进行工作时,可分为如下几个步骤:

  • 将监听器绑定到事件源,也就是注册监听器。
  • 事件发生时会触发监听器的成员方法,即事件处理器,传递事件对象。
  • 事件处理器通过事件对象获得事件源,并对事件源进行处理。
Servlet 事件监听器概述

在开发 Web 应用程序时,也经常会使用监听器,这个监听器也被称为 Servlet 事件监听器。Servlet 事件监听器就是一个实现了特定接口的 Java 程序,专门用于监听 Web 应用程序中 ServletContext、HttpSession 和 ServletRequest 等域对象的创建和销毁过程,监听这些域对象属性的修改以及感知绑定到 HttpSession 域中某个对象的状态。

Servlet 规范中共有 8 种监听器

类型描述
ServletContextListener用于监听 ServletContext 对象的创建与销毁过程
HttpSessionListener用于监听 HttpSession 对象的创建与销毁过程
ServletRequestListener用于监听 ServletRequest 对象的创建与销毁过程
ServletContextAttributeListener用于监听 ServletContext 对象中的属性变更
HttpSessionAttributeListener用于监听 HttpSession 对象中的属性变更
ServletRequestAttributeListener用于监听 ServletRequest 对象中的属性变更
HttpSessionBindingListener用于监听 JavaBean 对象绑定到 HttpSession 对象和从 HttpSession 对象解绑的事件
HttpSessionActivationListener用于监听 HttpSession 中对象活化和钝化的过程

HttpSession 对象从内存中转移至硬盘的过程称为钝化。HttpSession 对象从持久化的状态变为运行状态的过程被称为活化。

上述监听器根据监听事件的不同可以将其分为 3 类:

  • 用于监听域对象创建和销毁的事件监听器(ServletContextListener 接口、HttpSessionListener 接口、ServletRequestListener 接口)。
  • 用于监听域对象属性增加和删除的事件监听器(ServletContextAttributeListener 接口、HttpSessionAttributeListener 接口、ServletRequestAttributeListener 接口)。
  • 用于监听绑定到 HttpSession 域中某个对象状态的事件监听器(HttpSessionBindingListener 接口、HttpSessionActivationListener 接口)

在 Servlet 规范中,这 3 类事件监听器都定义了相应的接口,在编写事件监听程序时只需要实现对应的接口就可以。Web 服务器会根据监听器所实现的接口,把它注册到被监听的对象上,当触发了某个对象的监听事件时,Web 容器将会调用 Servlet 监听器与之相关的方法对事件进行处理。

监听域对象的生命周期

要想对 Servlet 域对象的生命周期进行监听,首先需要实现域对应的 ServletContextListener、HttpSessionListener 和 ServletRequestListener 接口,这些接口中的方法和执行过程非常类似。可以为每一个监听器编写一个单独的类,也可以用一个类来实现这 3 个接口,从而让这个类具有 3 个事件监听器的功能。

1. 创建监听器

MyListener.java

package com.xxx;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//@WebListener
public class MyListener implements
        ServletContextListener,
        HttpSessionListener,
        ServletRequestListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext对象被创建了...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext对象被销毁了...");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("ServletRequest对象被销毁了...");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("ServletRequest对象被创建了...");
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("HttpSession对象被创建了...");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("HttpSession对象被销毁了...");
    }
}

2. 添加监听器类信息

在 web.xml 中添加如下配置


	com.xxx.MyListener

3. 创建测试页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    $Title$
  
  
    ${pageContext.session.getAttribute("name")}
    <% session.setAttribute("name", "666666"); %>
  

4. 设置监听超时信息

在 web.xml 中添加如下配置:


  	1

5. 查看运行结果

1 分钟后控制台输出 session 销毁信息

监听对象属性变更

1. 创建测试页面

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Insert title here


    

这是一个测试对象属性信息监听器的页面

<% pageContext.getServletContext().setAttribute("username", "u1"); getServletContext().setAttribute("username", "t2"); getServletContext().removeAttribute("username"); session.setAttribute("username", "u1"); session.setAttribute("username", "t2"); session.removeAttribute("username"); request.setAttribute("username", "u1"); request.setAttribute("username", "t2"); request.removeAttribute("username"); %>

2. 创建监听器

MyAttributeListener.java

package com.xxx;

import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener
public class MyAttributeListener implements
        ServletContextAttributeListener,
        HttpSessionAttributeListener,
        ServletRequestAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        String name = scae.getName(); // 触发时间的属性名
        // e.getxxx()  通过事件获取事件源对象
        System.out.println("ServletContext 添加属性:" + name + "="
                + scae.getServletContext().getAttribute(name));
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        String name = scae.getName();
        System.out.println("ServletContext 移除属性:" + name);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        String name = scae.getName();
        System.out.println("ServletContext 替换属性:" + name + "="
                + scae.getServletContext().getAttribute(name));
    }

    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        System.out.println("ServletRequest 添加属性:" + name + "="
                + srae.getServletRequest().getAttribute(name));
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        System.out.println("ServletRequest 移除属性:" + name);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        System.out.println("ServletRequest 替换属性:" + name + "="
                + srae.getServletRequest().getAttribute(name));
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        String name = se.getName();
        System.out.println("HttpSession 添加属性:" + name + "="
                + se.getSession().getAttribute(name));
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        String name = se.getName();
        System.out.println("HttpSession 移除属性:" + name);
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        String name = se.getName();
        System.out.println("HttpSession 替换属性:" + name + "="
                + se.getSession().getAttribute(name));
    }
}

3. 运行结果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/425199.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号