菜鸟笔记
提升您的技术认知

java之Servlet

客户端与服务端交互原理

Http(超文本传输协议)

含义:http协议就相当于客户端和服务端定义好的一个规范,通过这个规范,所有人在请求和响应的过程中都需要遵循这样的规范

Http协议作用:规范了浏览器和服务器之间的数据交互

特点

  • 简单快速灵活
  • 无状态
  • 支持B/S和C/S架构

注意:HTTP1.1之后支持可持续连接

Http请求报文格式

Http请求方法

get与post请求区别

  • get请求参数直接显示在地址栏的,而post的请求参数放在请求体中
  • get方式不安全,post安全
  • get请求参数有限指,post没有限制
  • get只能传输字符数据,post可以传输字节数据

Http响应报文格式

Http响应状态码

Servlet 

含义:Servlet全称server applet,其是基于HTTP协议协议的在服务端生成的程序,我们把实现Servlet接口的java程序叫做Servlet程序

主要功能:交互式的浏览生成数据,生成动态web内容

servlet目录结构

servlet的使用

  • 导入Java Servlet API 的包
  • 写一个类,继承HttpServlet类
  • 重写doGet/doPost等方法
  • 配置web.xml映射路径
  • 配置tomcat(将写好的类部署到web服务器中)

1.导入Java Servlet API 的包

打开idea的File-Project Structure,在Modules的依赖窗口加jars(servlet-api.jar),从tomcat的lib目录中

2.写一个类,继承HttpServlet类,重写doGet/doPost等方法

public class MyServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("<h1>hello servlet</h1>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

注意:因为我要发get请求,所以我只在doGet方法中向浏览器输入内容

3.配置web.xml映射路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- web应用的名字 -->
    <display-name>项目名</display-name>
    <!-- 默认访问页面的列表 -->
    <welcome-file-list>
        <!-- 我们项目启动之后会默认访问的页面(包含以下几种) -->
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <!--web.xml文件映射路径-->
    <servlet>
        <servlet-name>myservlet</servlet-name>
        <servlet-class>com.msb.MyServlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>myservlet</servlet-name>
        <url-pattern>/first</url-pattern>
    </servlet-mapping>
</web-app>

注意:

  • 配置过程中的访问路径与类名通过servlet-name连接起来
  • 映射路径可以写多个
  • servlet-name可以任意写,但是相同的servlet-name表明一个特定的请求路径对应一个包名.类名
  • url-pattern写请求路径(里面可以有通配符*),servlet-class写包名.类名
  • 也可以多条路径访问同一个类,只需要多个相同的servlet-name对应不同的url-pattern即可
  • 上面的理解:收到该项目下的/first请求路径的请求叫myservlet,其会被com.msb.MyServlet1这个类处理(通过反射机制)
  • 也可以不写配置文件直接在servlet类上写注解@WebServlet(urlPatterns = {"uri"})代替路径映射标签,注意uri的前面必须有/

4.配置tomcat

打开Edit Configurations,添加tomcat

点击Deployment后点击右边的+号添加你项目的war包然后apply并ok

注意:访问路径前缀(虚拟项目名)标识的是某一项目的war包,因为可能将多个项目放入tomcat容器中

访问:localhost:8080/web1/first

servlet运行流程

过程:浏览器发起请求到web容器(tomcat),之后web容器产生两个对象(请求,响应)web容器根据请求url地址中的url信息在webapps目录下找到对应的项目文件夹(虚拟项目名),然后再web.xml中检索出对应的servlet,找到后调用并执行servlet的生命周期函数

servlet的生命周期

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}
  • 初始化:在开启服务并首次调用该服务时,servlet主动调用init方法,该方法只会被调用一次
  • 提供服务:用户每次发起请求servlet都会调用service方法,该方法可以被调用多次
  • 销毁:当服务关闭时servlet会主动调用destroy方法,该方法只会被调用一次

关于初始化:在servlet标签里面配置<load-on-startup>1</load-on-startup>就会在服务的开启时servlet主动调用init方法;里面的值为优先级展示,优先级由1到后越来越低,servlet会从优先级高的init方法到优先级低的方法依次调用

Servlet继承结构

Servlet接口<——GenericServlet抽象类<——HttpServlet抽象类(无抽象方法)

注意:GenericServlet抽象类并没对service方法做任何处理,而HttpServlet抽象类重写了service方法并进行了判断,重写内容为判断你发的请求是什么类型,什么类型的请求在service方法里面调用什么类型的方法(doGet/doPost)

HttpServletRequest对象

含义:Request对象用来解析请求参数,当浏览器访问服务器时,携带着一些请求参数,可以通过Servlet提供的Request对象提供的API来解析请求参数

注意:request对象封装了请求报文

获取请求行

String getMethod():获取请求中的请求方式

StringBuffer getRequestURL():获取请求完整地址

String getRequestURI():获取请求资源路径

String getScheme():获取请求中的协议

获取请求头

注意:由于请求头是Key:value键值对形式的,所以直接获取key就可以获得对应的value值

String getHeader("key"):获取对应key的请求头信息

Enumeration<String> getHeaderNames():获取请求头信息中的所有key的枚举对象

获取请求体

注意:

  • 由于请求体是Key:value键值对形式的,所以直接获取key就可以获得对应的value值
  • 无论请求方式是post还是get,获取用户数据的方式不变

String getParameter("key"):获得请求体中key所对应的value值

Enumeration<String> getParameterNames():获取用户数据中的所有key

String[] getParameterValues("key"):如果key是多值,那么就将key的多值封装成一个数组

        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            System.out.println(parameterNames.nextElement());
        }

其他方法

String getRemoteAddr():获取远程客户端地址

String getRemoteHost():获取远程客户端主机名称

int getRemotePort():获取远程客户端端口号

String getLocalAddr():获取本地计算机地址

String getLocalName():获取本地计算机名称

int getLocalPort():获取本地计算机端口号

void setAttribute(String var1, Object var2):在request对象内设置var1属性值为var2

Object getAttribute(String var1):在request对象内获取var1属性的值

void removeAttribute(String var1):在request对象内移除var1属性及值

String getQueryString():指获取查询字符串的值(也就是?后面的值,post请求不支持)

解决乱码

void setCharacterEncoding("utf-8"):设置请求编码格式为utf-8 

HttpServletResponse对象

含义:HttpServletResponse对象是服务器的响应对象,这个对象中封装了向客户端发送数据,发送响应头,发送响应状态码的方法

注意:rsponse对象封装了响应报文

设置响应头

void setHeader("key", "value"):设置响应头,按照k:v键值对形式,key相同时value可以被覆盖

void addHeader("key", "value"):设置响应头,按照k:v键值对形式,key相同value不可以被覆盖

其他常用方法

void sendError(状态码,"状态码信息"):设置响应状态

PrintWriter getWriter():获取打印流

ServletOutputStream getOutputStream():获取字节输出流

常用属性

void setCharacterEncoding("utf-8"):设置响应编码格式为utf-8

void setContentType("text/html;charset=utf-8"):让浏览器以html和utf8编码的方式解析数据

void setHeader("Access-Control-Allow-Origin","*"):允许任何源跨域

Servlet请求转发

含义:当浏览器发送请求访问服务器中的某一个资源时,该资源将请求转交给另外一个资源进行处理的过程

请求转发特点

  • 请求转发过程是一次请求,一次响应
  • 请求转发过程中request对象是同一个
  • 请求转发过程中,浏览器的地址没变化,所显示的页面是转发后的页面
  • 转发到另一个servlet后,原servlet就无法响应页面,但转发后的代码还是可以往后继续执行的
  • 转发前后的两个资源必须属于同一个Web应用,否则将无法进行转发

转发方式:请求对象.getRequestDispatcher("/servlet内部url地址或jsp页面").forward(请求对象, 响应对象);

注意:url的前面一定要有/

Servlet重定向

含义:属于客户端行为。服务器在收到客户端请求后,会通知客户端浏览器重新向另外一个 URL 发送请求,这称为请求重定向。它本质上是两次 HTTP 请求,对应两个 request 对象和两个 response对象。

重定向特点

  • 重定向前后是两次请求,两次响应
  • 重定向前后,浏览器地址栏地址会发生变化
  • 重定向前后request对象不是同一个
  • 重定向前后的两个资源可以来自不同的web应用,甚至可以来自不同的虚拟主机和服务器

重定向:响应对象.sendRedirect(String url)

请求转发和重定向区别

Cookie

前言:HTTP是一个无状态的协议,当一个客户端向服务端发送请求,在服务器返回响应后,连接就关闭了,在服务端不会保留连接信息

含义:Cookie是在客户端保持HTTP状态信息的技术

特点

  • cookie是在浏览器访问服务器的某个资源时,由web服务器在响应头传送给浏览器的数据
  • 浏览器如果保存了某个cookie,那么以后每次访问服务器的时候,都会在请求头传递给服务端(cookie默认在虚拟项目名对应的目录下都有效)
  • 一个cookie只能记录一种信息,是以key-value形式
  • 一个web站点可以给浏览器发送多个cookie(但最多存放20个),一个浏览器也可以存储多个站点的cookie(最多300个)
  • cookie大小有限制:4kb
  • cookie是有有效期的,若不设置有效期,则默认关闭浏览器失效

创建cookie

创建cookie:Cookie cookie = new Cookie(String name,String value)  

设置cookie

响应对象.addCookie(Cookie var1):将cookie设置到response中,返回值为void

cookie.setMaxAge(int expiry):为cookie设置有效期,单位为秒,返回值为void

cookie.setPath("/"):只要访问同一个Tomcat中所有的项目资源,都会携带Cookie,返回值为void

cookie.setPath("/cookie"):只要访问当前项目(cookie)中的所有资源,都会携带Cookie,返回值为void

cookie.setPath("/cookie/abc"):只要访问当前项目(cookie)的abc路径下的所有资源,都会携带Cookie,返回值为void

获取cookie

请求对象.getCookies():获得cookie数组

cookie.getName():获得cookie的name,返回值为string

cookie.getValue():获得cookie的值,返回值为string

删除和修改cookie

  • 对于不设置有效期的cookie,关闭浏览器后自动失效
  • 对于设置有效期的cookie,创建一个同名cookie将有效期设置为0再响应给浏览器
  • 修改cookie:新建一个重名cookie覆盖掉原有的cookie

Session

含义:session表示会话,在一段时间内,用户与服务器之间的一系列交互操作。

session对象:用户发送不同请求的时候,在服务器端保存不同请求共享数据的存储对象

特点

  1. session是依赖于cookie技术的服务器端的数据存储技术
  2. 由服务器进行创建
  3. 每个用户独立拥有一个session对象
  4. 默认存储时间是30分钟,有请求则刷新;关闭浏览器后session失效
  5. 因为session是依赖cookie技术实现的,所以session默认在虚拟项目名对应的目录下都有效

Session的流程

理解:session相当于在服务端开了一个房,服务端生成session后保存起来,将sessionid与会话结束时间传入cookie返回给浏览器,之后用户根据这个含有sessionid的cookie取出sessionid就可以打开对应的session房子得到相应数据。

session获取

获取session对象:HttpSession session = 请求对象.getSession()

session.getId():获取sessionid,返回值为string类型

session.getAttribute(String name):获取session属性值,返回值为Object

session设置

session.setAttribute(String name,Object value):设置session属性,返回值为void

session.setMaxInactiveInterval(int n):修改session时长,以秒为单位,返回值为void 

    <!--web.xml文件内-->
    <session-config>
        <!--修改session过期时间,以分钟为单位-->
        <session-timeout>1</session-timeout>
    </session-config>

session删除

session.invalidate():注销session,返回值为void

session.removeAttribute(String name):移除session中名为name的属性,返回值为void

cookie与session类比

  • cookie:服务端给客户端一个信件,信件里面记录了你的信息,客户端下次访问服务端带上信件就可以了
  • session:服务器登记你来过了,下次你来的时候匹配你(只需要确认是你就行)

理解:

  • session是存在服务器上的,安全;而cookie是存在浏览器上的,不安全
  • session数据的取出依赖于sessionid,而sessionid存在于cookie中
  • 名与值类型:session:string和object、cookie:string和string

ServletContext对象

前言:web容器启动的时候,他会为每个web程序都创建一个对应的servletContext对象,它代表当前的web项目(虚拟项目名下面的目录)

特点:

  • 其由服务器创建
  • 所有用户共享一个ServletContext对象
  • 每一个web项目对应的是一个ServletContext对象
  • ServletContext对象是web服务器中一个已知路径的根路径(原虚拟项目名->文件名)

获取ServletContext对象

ServletContext servletContext = this.getServletContext();

ServletContext servletContext = this.getServletConfig().getServletContext();

ServletContext servletContext = req.getSession().getServletContext();

下面的参数为/虚拟项目名/具体的servlet路径映射(多余)

ServletContext servletContext = this.getServletContext().getContext("/servletContext/three")

注意:在同一个web应用中获取到的ServletContext对象相同

ServletContext常用方法

获取web.xml文件中的公共属性(初始化参数)

    <!--web.xml文件内-->
    <context-param>
        <!--注意里面的name和value的数据类型均为string-->
        <param-name>name</param-name>
        <param-value>value</param-value>
    </context-param>
    <!--注意:如果有多个属性,使用多个context-param标签-->

String getInitParameter(String name):获取初始化参数中name属性对应的值

Enumeration<String> getInitParameterNames():获取所有初始化参数名

        Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){
            System.out.println(initParameterNames.nextElement());
        }

String getRealPath(String name):获得此项目内文件名为name的相对于电脑盘符所在的真实路径

String getContextPath():获取虚拟项目名路径

请求转发:servletContext对象.getRequestDispatcher(String uri).forward(req, resp)

ServletConfig对象

含义:ServletConfig对象是Servlet的专属配置对象,每个Servlet都单独拥有一个ServletConfig对象,主要用来获取web.xml文件中的初始化信息。

为每个Servlet程序设置初始化信息,通过ServletConfig对象来获取

获取ServletConfig对象:ServletConfig servletConfig = this.getServletConfig()

获取初始化参数name:String getInitParameter(String name)

获得所有的初始化key:Enumeration<String> getInitParameterNames()

    <!--web.xml文件内-->
    <servlet>
        <servlet-name>servletconfig</servlet-name>
        <servlet-class>cn.tedu.ConfigServlet</servlet-class>
        <!--如果写多个初始化参数就写多个init-param标签-->
        <init-param>
            <!--注意:初始化的name和value都为string类型-->
            <param-name>name</param-name>
            <param-value>value</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletconfig</servlet-name>
        <url-pattern>/one</url-pattern>
    </servlet-mapping>
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig servletConfig = this.getServletConfig();
        //获取初始值
        String value = servletConfig.getInitParameter("name");
        System.out.println(value);
    }

过滤器

含义:过滤器是能够对web请求和web响应的头属性和内容体进行操作的一种特殊web组件

注意:

  • 过滤器的特殊之处在于本身并不能够直接生成web请求和响应,而是拦截web请求和响应,以便查看、提取或以某种方式操作客户机和服务器之间交换的数据
  • 可以用注解@WebFilter(urlPatterns = {"uri"})代替web.xml中的配置文件来让tomcat识别,只需要将该注解放到对应的过滤器类上

过滤器的功能

  • 分析web请求,对输入数据进行预处理
  • 阻止web请求和响应的进行
  • 根据功能改动请求的头信息和数据体
  • 与其他web资源协作

过滤器的核心接口

  • javax.servlet.Filter
  • javax.servlet.FilterConfig
  • javax.servlet.FilterChain

过滤器的工作原理

过滤器的生命周期

public interface Filter {
    //用于完成tomcat的初始化,tomcat的启动时执行一次
    void init(FilterConfig var1) throws ServletException;
    //进行处理,var3用于放行
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    //销毁功能,tomcat关闭的时候执行一次
    void destroy();
}

FilterConfig对象

作用:来获取过滤器的初始化参数和Servlet的相关信息。

常用方法

过滤器的使用

public class MyFilter implements Filter {
    //过滤器的生命周期函数
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String name = filterConfig.getInitParameter("name");
        System.out.println("初始化参数值为"+name);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter逻辑处理");
        servletResponse.setContentType("text/html;charset=utf-8");
        //添加此语句之后放行
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("放行后");
    }
    @Override
    public void destroy() {
        System.out.println("我是filter销毁");
    }
}
    <!--web.xml文件内-->
    <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>com.jt.MyFilter</filter-class>
        <!--如果有多个初始化参数需写多个该标签-->
        <init-param>
            <!--注意:初始化参数的name和value为String类型-->
            <param-name>name</param-name>
            <param-value>value</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>myFilter</filter-name>
        <!--匹配本项目内所有请求-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在web.xml文件中指定过滤器过滤请求

  • /*:匹配本项目中的所有请求
  • /*.do:匹配本项目中所有后缀为.do的请求(servlet路径中带.do)
  • /filter.do:匹配本项目中请求为filter.do的请求

注意:

  • 使用过滤器必须实现Filter接口以及配置web.xml或注解
  • 每次Filter能匹配的路径发起请求都先经过过滤器,过滤器优先于servlet程序执行
  • 经过过滤器的请求经由过滤器链的doFilter方法进行放行传给下一个过滤器或servlet程序(不调用的话会阻塞),待下一个程序都执行完再执行过滤器链的doFilter方法后面的方法
  • 过滤器仅能处理本项目内的servlet程序,其他项目的不可以

过滤器链(FilterChain)

含义:在一个Web应用中,也可以部署多个过滤器,这些过滤器组成了一个过滤器链。

过滤器链执行流程

注意:code1为过滤器链的doFilter方法之前的代码,code2为过滤器链的doFilter方法之后的代码

过滤器链的执行顺序  

过滤器链中的执行顺序按照web.xml中<filter-mapping>标签的配置顺序决定的(只要满足过滤器链的请求都会走过滤器链)此标签越靠前的过滤器在过滤器链中越先执行

原因:路径查找在web.xml中是从头到尾进行查找,越在前面越先被查找到就越先被执行,找到路径后直接映射到具体的filter类执行具体逻辑

监听器

含义:Servlet监听器用于监听一些重要的事件发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理

注意:

  • 通过实现Servlet API提供的Listense接口,可以在监听正在执行的某一个程序,并且根据程序的需求做出适当的响应
  • 一般都通过web.xml配置监听器,不过也可以在监听器类上加@WebListener来让tomcat识别
  • 监听器优先于过滤器执行,过滤器优先于servlet程序执行

三种监听器

  • HttpSession监听器:监听HttpSession对象,可以使web应用了解会话期间的状态并作出反应
  • ServletContext监听器:监听ServletContext对象可以使web应用得知web组件的加载和卸载等运行情况
  • ServletRequest监听器:监听ServletRequest对象,可以使web应用控制web请求的生命周期

ServletRequestListener

作用:监听servlet中request对象的创建及销毁

servletRequestEvent对象方法

servletRequestEvent.getServletContext():获得servletContext对象

servletRequestEvent.getServletRequest():获得ServletRequest对象

ServletRequestAttributeListener

作用:监听servlet中request对象属性的相关配置(属性的添加,删除和修改)

ServletRequestAttributeEvent方法

servletRequestAttributeEvent.getName():获得属性的名,返回值为string类型servletRequestAttributeEvent.getValue():获得属性的值,返回值为Object类型

public class MyListener implements ServletRequestListener, ServletRequestAttributeListener {
    //ServletRequestListener
    //request对象被销毁时调用
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("rquest对象被销毁");
    }
    //request对象被调用时调用
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("request对象被创建");
    }

    //ServletRequestAttributeListener
    //监听向request中添加属性
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("监听向request作用域添加数据");
        System.out.println("添加了"+servletRequestAttributeEvent.getName()+"值为"+servletRequestAttributeEvent.getValue());
    }
    //监听向request中移除属性
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("监听向request中移除数据");
        System.out.println("移除了"+servletRequestAttributeEvent.getName()+"值为"+servletRequestAttributeEvent.getValue());
    }
    //监听向request中属性的修改
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("监听向request中属性的修改");
        System.out.println("替换了"+servletRequestAttributeEvent.getName()+"新值为"+servletRequestAttributeEvent.getValue());
    }
}
    <listener>
        <!--包名.类名-->
        <listener-class>com.msb.listener.MyListener</listener-class>
    </listener>

ServletContextListener

作用:监听ServletContext对象的创建和销毁

ServletContextEvent对象方法

servletContextEvent.getServletContext():获得ServletContext对象

ServletContextAttributeListener

作用:监听ServletContext对象属性的相关配置(属性的添加,删除和修改)

ServletContextAttributeEvent对象方法

servletContextAttributeEvent.getName():获得ServletContext属性名,返回值为string类型

servletContextAttributeEvent.getValue():获得ServletContext属性值,返回值为Object类型

public class MyListener1 implements ServletContextListener, ServletContextAttributeListener {
    //ServletContextListener
    //ServletContext对象创建时调用
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("servletContext对象创建");
    }
    //ServletContext对象销毁时调用
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("servletContext对象销毁");
    }

    //ServletContextAttributeListener
    //ServletContext属性增加时调用
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("增加了"+servletContextAttributeEvent.getName()+"属性,值为"+servletContextAttributeEvent.getValue());
    }
    //ServletContext属性移除时嗲用
    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("移除了"+servletContextAttributeEvent.getName()+"属性,值为"+servletContextAttributeEvent.getValue());
    }
    //ServletContext属性修改时调用
    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("修改了"+servletContextAttributeEvent.getName()+"属性,新值为"+servletContextAttributeEvent.getValue());
    }
}
    <!--如果配置多个监听器的话应该写多个标签-->
    <listener>
        <listener-class>com.msb.listener.MyListener1</listener-class>
    </listener>

HttpSessionListener

作用:监听session对象的创建和销毁

httpSessionEvent对象方法

httpSessionEvent.getSession():获取session对象

HttpSessionAttributeListener

作用:监听session对象属性的相关配置(属性的添加,删除和修改)

httpSessionBindingEvent对象方法

httpSessionBindingEvent.getName():获得session属性名,返回值为string类型

httpSessionBindingEvent.getValue():获得session属性值,返回值为Object类型

httpSessionBindingEvent.getSession():获得session对象

public class MyListener2 implements HttpSessionListener, HttpSessionAttributeListener {
    //HttpSessionListener
    //session对象被创建时调用
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("session对象被创建");
    }
    //session对象被销毁时调用
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session对象被销毁");
    }

    //HttpSessionAttributeListener
    //session添加属性时调用
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session添加属性时调用");
        System.out.println();
    }
    //session移除属性时调用
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session移除属性时调用");
    }
    //session修改属性时调用
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session修改属性时调用");
    }
}
    <listener>
        <listener-class>com.msb.listener.MyListener2</listener-class>
    </listener>