Servlet基础

1、Servlet简介

​ Servlet:服务端小程序,由服务器调用执行,主要运行在服务端。

Servlet程序处理步骤:

  • 客户端浏览器通过http提出请求
  • web服务器接收该请求并将其发送给Servlet。如果这个Servlet尚未被加载,Web服务器则将它加载到Java虚拟机(JVM)中并执行它
  • Servlet程序接受该HTTP请求并执行某种处理
  • Servlet程序会将处理后的结果向Web服务器返回应答
  • Web服务器将从Servlet接收应答并发回到客户端

注意:Servlet程序最重要的一个接口是Servlet接口,在此接口下定义了一个GenericServlet子类。但是一般不会去继承此子类。而是根据所选择的协议选择GenericServlet的子类去继承。现在采用HTTP协议,所以选择继承GenericServlet的子类HttpServlet。

2、Servlet程序的创建

HelloServlet

package com.whw.myservlet;

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 HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter printWriter=resp.getWriter();
        printWriter.println("<html>");
        printWriter.println("<head><title>JavaServlet</title></head>");
        printWriter.println("<body>");
        printWriter.println("<h1>Hello World!<h1>");
        printWriter.println("</body>");
        printWriter.println("</html>");
        printWriter.close();
    }
}

​ Servlet程序编译完成后无法直接访问。因为所有的Servlet程序都是以.class文件形式存在的。所以必须在WEB-INFO\web.xml中进行相关配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <servlet>
        <!--Servlet程序名称-->
        <servlet-name>helloservlet</servlet-name>
        <!--Servlet程序类路径-->
        <servlet-class>com.whw.myservlet.HelloServlet</servlet-class>
    </servlet>

    <!--配置Servlet映射-->
    <servlet-mapping>
        <!--指定映射对应的Servlet程序名称-->
        <servlet-name>helloservlet</servlet-name>
        <!--指定访问路径模式-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

每一个Servlet都可以配置多个名称,只需要增加对应的mapping映射元素即可

	<servlet-mapping>
        <servlet-name>helloservlet</servlet-name>
        <url-pattern>/aaa.asp</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>helloservlet</servlet-name>
        <url-pattern>/aaa/bb.www</url-pattern>
    </servlet-mapping>

3、Servlet与表单

input.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="InputServlet" method="post">
    输入内容:<input type="text" name="info">
    <input type="submit" value="提交">
</form>
</body>
</html>

InputServlet

因为表单是采用post方式提交的,所以此处使用重载doPost方法去处理

package com.whw.myservlet;

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 InputServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String info = req.getParameter("info");
        PrintWriter printWriter = resp.getWriter();
        printWriter.println("<html>");
        printWriter.println("<head><title>JavaServlet</title></head>");
        printWriter.println("<body>");
        printWriter.println("<h1>" + info + "<h1>");
        printWriter.println("</body>");
        printWriter.println("</html>");
        printWriter.close();
    }
}

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <servlet>
        <servlet-name>inputservlet</servlet-name>
        <servlet-class>com.whw.myservlet.InputServlet</servlet-class>
    </servlet>

    <!--配置inputservlet的Servlet映射-->
    <servlet-mapping>
        <servlet-name>inputservlet</servlet-name>
        <!--此路径要和form表单上提交的路径一致-->
        <url-pattern>/InputServlet</url-pattern>
    </servlet-mapping>

</web-app>

4、Servlet生命周期

生命周期对应方法

方法 说明
void init() throws ServletException; Servlet初始化时调用
void init(ServletConfig config) throws ServletException; Servlet初始化时调用,可以通过ServletConfig读取配置信息
void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException; Servlet服务,一般不会直接重写此方法,而是使用doGet()或doPost()方法
void destroy(); Servlet销毁时调用

生命周期的说明:

1、加载Servlet

​ Web容器负责加载Servlet,当Web容器启动时或者是第一次使用这个Servlet时,容器会负责创建Servlet实例,但是用户必须通过部署描述符(web.xml)指定Servlet的位置(Servlet所在的包.类名称),成功加载后,Web容器会通过反射的方式对Servlet进行实例化。

2、初始化

​ 当一个Servlet被实例化后,容器将调用init()方法初始化这个对象,初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作。如:建立数据库连接、读取资源文件信息等,如果初始化失败,则此Servlet将直接被卸载。通常情况下Servlet只初始化一次,销毁一次。可以多次服务。如果Servlet长时间不使用,也会被容器自动销毁,再次使用需要重新初始化,所以,特殊情况下也可能会初始化多次,销毁多次。

3、处理服务

​ 当有请求提交时,Servlet将调用service()方法(常用的是doGet()或doPost())进行处理。在service()方法中,Servlet可以通过ServletRequest接收客户的请求,也可以利用ServletResponse设置响应信息。

4、销毁

​ 当Web容器关闭或者检测到一个Servlet要从容器中被删除时,会自动调用destory()方法,以便让该实例释放掉所占用的资源

5、卸载

​ 当一个Servlet调用完destory()方法后,此实例将等待被垃圾回收器回收,如果需要再次使用此Servlet时,会重新调用init()方法初始化。

测试

package com.whw.myservlet;

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

public class LifeCycleServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("执行初始化-->init");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("执行服务-->service");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("执行销毁-->destroy");
    }
}

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <servlet>
        <servlet-name>lifecycleservlet</servlet-name>
        <servlet-class>com.whw.myservlet.LifeCycleServlet</servlet-class>
        <!--配置容器启动时初始化Servlet,默认是容器启动不初始化Servlet,只有发起第一次Servlet相关请求时才初始化Servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>lifecycleservlet</servlet-name>
        <url-pattern>/life</url-pattern>
    </servlet-mapping>
</web-app>

注意:

配置容器启动时初始化Servlet

<!--配置容器启动时初始化Servlet,默认是容器启动不初始化Servlet,只有发起第一次Servlet相关请求时才初始化Servlet-->        
<load-on-startup>1</load-on-startup>

如果自定义Servlet重写了service方法,则doGet()和doPost()方法则不再起作用,而是直接使用service()方法进行处理。因为在HttpServlet类中已经重写了service()方法

5、获取初始化配置信息

​ 在jsp中存在内置对象config,可以通过config获取web.xml中相关的配置信息。此对象实际上是ServletConfig接口的实例。每个Servlet初始化参数都可以配置多个。

package com.whw.myservlet;

import javax.servlet.ServletConfig;
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.util.Enumeration;

public class InitParamServlet extends HttpServlet {
    
    private ServletConfig servletConfig = null;
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.servletConfig = config;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("获取指定初始化参数:" + servletConfig.getInitParameter("addr"));
        System.out.println("获取所有参数:");
        Enumeration<String> paramEnumeration = servletConfig.getInitParameterNames();
        while (paramEnumeration.hasMoreElements()) {
            String paramName=paramEnumeration.nextElement();
            System.out.println("参数名:" + paramName+"  参数值:"+servletConfig.getInitParameter(paramName));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <!--初始化参数Servlet-->
    <servlet>
        <servlet-name>initparamservlet</servlet-name>
        <servlet-class>com.whw.myservlet.InitParamServlet</servlet-class>
        <init-param>
            <param-name>addr</param-name>
            <param-value>北京朝阳</param-value>
        </init-param>
        <init-param>
            <param-name>name</param-name>
            <param-value>中国</param-value>
        </init-param>
    </servlet>

    <!--配置initparamservlet的Servlet映射-->
    <servlet-mapping>
        <servlet-name>initparamservlet</servlet-name>
        <url-pattern>/initparam</url-pattern>
    </servlet-mapping>
</web-app>

获取session相关的信息

package com.whw.myservlet;

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

public class SessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        System.out.println("SessionID-->" + session.getId());
        session.setAttribute("username", "wangwei");
        System.out.println("username:" + session.getAttribute("username"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <!--配置sessionservlet-->
    <servlet>
        <servlet-name>sessionservlet</servlet-name>
        <servlet-class>com.whw.myservlet.SessionServlet</servlet-class>
    </servlet>

    <!--配置sessionservlet的Servlet映射-->
    <servlet-mapping>
        <servlet-name>sessionservlet</servlet-name>
        <url-pattern>/session</url-pattern>
    </servlet-mapping>
</web-app>

获取ServletContext:Servlet的上下文

package com.whw.myservlet;

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

public class SevletContextServlet extends HttpServlet {
    private ServletContext servletContext=null;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过父类的getServletContext()获取Servlet上下文
        servletContext=super.getServletContext();
        System.out.println(servletContext.getRealPath("/"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

//输出结果:E:\JavaGit\JavaServlet\out\artifacts\web_war_exploded\

6、Servlet跳转

​ 在html或者jsp中可以通过表单或超链接跳转进Servlet。从Servlet中也可以跳进其他的Servlet或者Html、Jsp页面。

6.1 客户端跳转

package com.whw.myservlet;

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

public class ClientRedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().setAttribute("username","whw");
        req.setAttribute("info","java");
        resp.sendRedirect("get_info.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <!--配置clientRedirectServlet-->
    <servlet>
        <servlet-name>clientRedirectServlet</servlet-name>
        <servlet-class>com.whw.myservlet.ClientRedirectServlet</servlet-class>
    </servlet>

    <!--配置clientRedirectServlet的Servlet映射-->
    <servlet-mapping>
        <servlet-name>clientRedirectServlet</servlet-name>
        <url-pattern>/clientredirect</url-pattern>
    </servlet-mapping>
</web-app>

get_info.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>session=<%=session.getAttribute("username")%>
</h3>
<h3>param=<%=request.getAttribute("info")%>
</h3>
</body>
</html>

输出结果:

session=whw
param=null

说明:从程序的输出结果可以看出,由于客户端跳转,所以跳转后的地址栏会改变。但是现在只能接收session范围内的内容。而request属性范围内的内容无法接收到。是因为request属性范围内的内容只能在服务器端跳转有效。

6.2 服务器端跳转

​ 在Servlet中没有想jsp:forward这样的指令。要想实现服务器端跳转只能依靠RequestDispatcher接口完成。

包含方法 说明
void forward(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; 页面跳转
void include(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; 页面包含
package com.whw.myservlet;

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

public class ServerRedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置session属性
        req.getSession().setAttribute("username", "whw");
        //设置request属性
        req.setAttribute("info", "java");
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("get_info.jsp");
        //服务器端跳转
        requestDispatcher.forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--Servlet相关配置-->
    <servlet>
        <servlet-name>serverRedirectServlet</servlet-name>
        <servlet-class>com.whw.myservlet.ServerRedirectServlet</servlet-class>
    </servlet>

    <!--配置serverRedirectServlet的Servlet映射-->
    <servlet-mapping>
        <servlet-name>serverRedirectServlet</servlet-name>
        <url-pattern>/serverredirect</url-pattern>
    </servlet-mapping>
</web-app>

输出结果:

session=whw
param=java

7、过滤器

​ 过滤器是一种组件的形式绑定到web应用程序当中的,与其他的web应用程序组件不同的是,过滤器采用的是“链”的方式进行处理的,当需要限制用户访问某些资源或者再处理请求时提前处理某些资源,可以使用过滤器来完成。

实现过滤器:

​ 直接让一个类实现javax.servlet.Filter接口即可。

Filter接口方法说明:

方法 说明
void init(FilterConfig var1) throws ServletException; 过滤器初始化(容器启动时初始化)时调用,可通过FilterConfig获取配置的初始化参数
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; 完成具体的过滤操作,通过FilterChain让请求继续向下传递
void destroy(); 过滤器销毁时使用

FilterChain主要作用是将用户的请求继续向下传递给其他的过滤器或Servlet。其也有一个doFilter方法:

方法 描述
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException; 将请求继续向下传递

自定义SimpleFilter过滤器

package com.whw.filter;

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

public class SimpleFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String initParam = filterConfig.getInitParameter("ref");
        System.out.println("我是初始化参数:" + initParam);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("开始执行doFilter()方法之前");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("执行doFilter()方法之后");
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--过滤器配置-->
    <filter>
        <filter-name>simpleFilter</filter-name>
        <filter-class>com.whw.filter.SimpleFilter</filter-class>
        <init-param>
            <param-name>ref</param-name>
            <param-value>我是simpleFilter的参数</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>simpleFilter</filter-name>
        <!--此处的url-pattern表示的是过滤器的过滤位置。/*表示对一切url都进行过滤。filter-mapping可以添加多个,已完成对多个路径的过滤-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

输出结果:

我是初始化参数:我是simpleFilter的参数
执行初始化-->init
[2020-05-08 06:13:38,392] Artifact web:war exploded: Artifact is deployed successfully
[2020-05-08 06:13:38,392] Artifact web:war exploded: Deploy took 579 milliseconds
开始执行doFilter()方法之前
执行doFilter()方法之后
开始执行doFilter()方法之前
执行doFilter()方法之后

由输出结果可见:

​ 过滤器只在容器启动时初始化了一次。doFilter方法执行了两次。一次是FilterChain操作,一次是在FilterChain链操作之后。

过滤器应用一(实现统一编码):

package com.whw.filter;

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

public class EncodingFilter implements Filter {

    private String charSet;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.charSet=filterConfig.getInitParameter("charset");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       servletRequest.setCharacterEncoding(charSet);
    }

    @Override
    public void destroy() {

    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--编码过滤器-->
    <filter>
        <filter-name>encodingfilter</filter-name>
        <filter-class>com.whw.filter.EncodingFilter</filter-class>
        <!--指定过滤器初始化参数-->
        <init-param>
            <param-name>charsert</param-name>
            <param-value>GBK</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingfilter</filter-name>
        <!--指定过滤的地址-->
        <url-pattern>/whwservlet/*</url-pattern>
    </filter-mapping>
</web-app>

过滤器应用二(登录校验)

package com.whw.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //向下转型,获取session
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        //判断用户是否存在
        if (session.getAttribute("userid") != null) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //服务器端跳转
            RequestDispatcher requestDispatcher = servletRequest.getRequestDispatcher("login.jsp");
            requestDispatcher.forward(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--登录校验过滤器-->
    <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>com.whw.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>loginFilter</filter-name>
        <!--指定过滤的地址-->
        <url-pattern>/whwservlet/*</url-pattern>
    </filter-mapping>
</web-app>

8、监听器

​ 在web的Servlet程序中可以对application、session、request三种操作进行监听。

8.1 对application监听

​ 对application监听,实际上就是对ServletContext(Servlet上下文)监听,主要使用ServletContextListenerServletContextAttributeListener两个接口

ServletContextListener接口:

方法 说明
void contextInitialized(ServletContextEvent var1); 容器启动时触发
void contextDestroyed(ServletContextEvent var1); 容器销毁时触发

监听application

package com.whw.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyApplicationListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("上下文初始化时触发");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("容器销毁时触发");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--application监听器-->
    <listener>
        <listener-class>com.whw.listener.MyApplicationListener</listener-class>
    </listener>
</web-app>

监听application attribute

package com.whw.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyApplicationAttrListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("增加属性,属性名:"+servletContextAttributeEvent.getName()+";属性值:"+servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("删除属性,属性名:"+servletContextAttributeEvent.getName()+";属性值:"+servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("替换属性,属性名:"+servletContextAttributeEvent.getName()+";属性值:"+servletContextAttributeEvent.getValue());
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--application属性监听器-->
    <listener>
        <listener-class>com.whw.listener.MyApplicationAttrListener</listener-class>
    </listener>
</web-app>

application_attr_add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新增application属性</title>
</head>
<body>
<%
    application.setAttribute("info","java");
%>
</body>
</html>

application_attr_remove.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>移除application属性</title>
</head>
<body>
<%
    application.removeAttribute("info");
%>
</body>
</html>

8.2 对session监听

​ 对session的监听操作主要使用HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener接口。

session状态监听:HttpSessionListener接口

​ 监听session的创建和销毁。可以实现javax.servlet.http.HttpSessionListener接口。

方法 描述
void sessionCreated(HttpSessionEvent var1); 监听session创建
void sessionDestroyed(HttpSessionEvent var1); 监听session销毁
package com.whw.listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MySessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("创建session,ID为:"+httpSessionEvent.getSession().getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("销毁session,ID为:"+httpSessionEvent.getSession().getId());
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--session状态监听-->
    <listener>
        <listener-class>com.whw.listener.MySessionListener</listener-class>
    </listener>
</web-app>

session销毁方式:

  • 调用session的invalidate()方法销毁
  • web.xml配置session过期时间
    <!--配置session5分钟后过期-->
    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

session属性监听:HttpSessionAttributeListener接口

package com.whw.listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MySessionAttrListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("新增session属性,属性名:"+httpSessionBindingEvent.getName()+";属性值:"+httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("移除session属性,属性名:"+httpSessionBindingEvent.getName()+";属性值:"+httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("替换session属性,属性名:"+httpSessionBindingEvent.getName()+";属性值:"+httpSessionBindingEvent.getValue());
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--session属性监听-->
    <listener>
        <listener-class>com.whw.listener.MySessionAttrListener</listener-class>
    </listener>
</web-app>

session_attr_add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>session属性增加</title>
</head>
<body>
<%
    session.setAttribute("info", "java");
%>
</body>
</html>

注意:此种属性监听必须在web.xml中进行配置。下面的监听方式不用在web.xml中进行配置

session属性监听:HttpSessionBindingListener

方法 描述
void valueBound(HttpSessionBindingEvent var1); 绑定对象到session时触发
void valueUnbound(HttpSessionBindingEvent var1); 从session中移除对象时触发
package com.whw.listener;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class MySessionAttributeListener implements HttpSessionBindingListener {
    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("在session中保存对象,对象名:"+httpSessionBindingEvent.getName()+";对象值:"+httpSessionBindingEvent.getValue());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("在session中移除对象,对象名:"+httpSessionBindingEvent.getName()+";对象值:"+httpSessionBindingEvent.getValue());
    }
}

无需web.xml配置

8.3 对request监听

​ 对request监听,主要实现ServletRequestListener接口和ServletRequestAttributeListener接口

监听request状态:ServletRequestListener接口

package com.whw.listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("创建请求");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("销毁请求");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--request状态监听-->
    <listener>
        <listener-class>com.whw.listener.MyRequestListener</listener-class>
    </listener>
</web-app>

监听request属性:ServletRequestAttributeListener接口

package com.whw.listener;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class MyRequestAttrListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("增加属性");
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("移除属性");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("替换属性");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--request属性监听-->
    <listener>
        <listener-class>com.whw.listener.MySessionAttrListener</listener-class>
    </listener>
</web-app>
posted @ 2021-06-09 10:50  码农小匠  阅读(61)  评论(0编辑  收藏  举报