• 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-INFOweb.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:JavaGitJavaServletoutartifactsweb_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>
    
  • 相关阅读:
    mysql优化——语句优化小技巧
    mysql优化——索引与索引优化
    Mysql存储引擎
    Mysql优化技术
    数据库设计——三范式
    java多线程(二)——用到的设计模式
    java多线程(一)
    ubuntu下如何查看用户登录及用户操作相关信息
    hdu 2546
    hdu 2955
  • 原文地址:https://www.cnblogs.com/giswhw/p/14865969.html
Copyright © 2020-2023  润新知