zoukankan      html  css  js  c++  java
  • Servlet 学习(二)

    Servlet 体系结构

    Servlet的实现方式

    1、实现 javax.servlet.Servlet 接口 ( 最底层,最原始 )

    测试案例:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Servlet Life Cycle</title>
    </head>
    <body>
    
        <h3>Servlet的实现方式:</h3>
        
        <h5>1、实现 javax.servlet.Servlet 接口 ( 最底层,最原始 ) </h5>
        <form action="/Servlet/first" method="post">
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        
        <h5>2、继承 javax.servlet.GenericServlet 类,实现 service 方法</h5>
        <form action="/Servlet/second" method="post">
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        
        <form action="/Servlet/second/abc" method="post">
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        
        <form action="/Servlet/second/xyz/abc" method="post">
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        
        <h5>3、继承 javax.servlet.http.HttpServlet 类 ,重写 doGet 和 doPost 方法</h5>
        <form action="/Servlet/third" method="get">
            GET: 
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        <form action="/Servlet/third" method="post">
            POST: 
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        
        <h5>4、继承 javax.servlet.http.HttpServlet 类 ,重写 service( HttpServletRequest , HttpServletResponse ) 方法</h5>
        <form action="/Servlet/forth" method="get">
            GET: 
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
        <form action="/Servlet/forth" method="post">
            POST: 
            <input type="text" name="username" placeholder="用户名">
            <input type="password" name="password" placeholder="密码">
            <input type="submit" value="提交" >
        </form>
    
    </body>
    </html>
    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>FirstServlet</servlet-name>
            <servlet-class>ecut.lifecycle.FirstServlet</servlet-class>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>FirstServlet</servlet-name>
            <url-pattern>/first</url-pattern>
        </servlet-mapping>
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>SecondServlet</servlet-name>
            <servlet-class>ecut.lifecycle.SecondServlet</servlet-class>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>SecondServlet</servlet-name>
            <url-pattern>/second</url-pattern>
            <url-pattern>/second/*</url-pattern>
        </servlet-mapping>
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>ThirdServlet</servlet-name>
            <servlet-class>ecut.lifecycle.ThirdServlet</servlet-class>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>ThirdServlet</servlet-name>
            <url-pattern>/third</url-pattern>
        </servlet-mapping>
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>ForthServlet</servlet-name>
            <servlet-class>ecut.lifecycle.ForthServlet</servlet-class>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>ForthServlet</servlet-name>
            <url-pattern>/forth</url-pattern>
        </servlet-mapping>
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>LifeCycleServlet</servlet-name>
            <servlet-class>ecut.lifecycle.LifeCycleServlet</servlet-class>
            <!-- 当容器 加载当前的WEB应用时就完成对 该 Servlet 的类加载、实例化、初始化操作 -->
            <!-- 数字代表加载优先级,默认值-1访问再加载 -->
            <load-on-startup>0</load-on-startup>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>LifeCycleServlet</servlet-name>
            <url-pattern>/cycle</url-pattern>
        </servlet-mapping>
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>ConfigurationServlet</servlet-name>
            <servlet-class>ecut.lifecycle.ConfigurationServlet</servlet-class>
            <!-- 指定初始化参数 -->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>content-type</param-name>
                <param-value>text/html</param-value>
            </init-param>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>ConfigurationServlet</servlet-name>
            <url-pattern>/config</url-pattern>
        </servlet-mapping>
        
    </web-app>
    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class FirstServlet implements Servlet {
    
        @Override
        public void init(ServletConfig config) throws ServletException {
            System.out.println( "初始化" );
        }
    
        @Override
        public void service(ServletRequest req , ServletResponse resp ) throws ServletException, IOException {
            System.out.println( "服务" );
            
            req.setCharacterEncoding( "UTF-8" );
            resp.setCharacterEncoding( "UTF-8" );
            
            // 接受来自客户端的数据
            String username = req.getParameter( "username" );
            System.out.println( "username : " + username );
            String password = req.getParameter( "password" );
            System.out.println( "password : " + password );
            
            // 向客户端生成响应数据
            resp.setContentType( "text/html;charset=UTF-8" );
            PrintWriter w = resp.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>你好 , " + username + " !</h1>" );        
        }
        
        @Override
        public void destroy() {
            System.out.println( "销毁" );
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }

    运行结果如下:

     

    信息: Server startup in 350 ms
    初始化
    服务
    username : AmyZheng
    password : 123456

    2、继承 javax.servlet.GenericServlet 类,实现 service 方法

    测试案例:

    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class SecondServlet extends GenericServlet{
    
        private static final long serialVersionUID = -2575698410270033395L;
    
        @Override
        public void service(ServletRequest req , ServletResponse resp) throws ServletException, IOException {
            
            req.setCharacterEncoding( "UTF-8" );
            resp.setCharacterEncoding( "UTF-8" );
            
            // 接受来自客户端的数据
            String username = req.getParameter( "username" );
            System.out.println( "username : " + username );
            String password = req.getParameter( "password" );
            System.out.println( "password : " + password );
            
            // 向客户端生成响应数据
            resp.setContentType( "text/html;charset=UTF-8" );
            PrintWriter w = resp.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>你好 , " + username + " !</h1>" );
            
        }
    
    }

    运行结果如下:

    username : AmyZheng
    password : AmyZheng

    username : AmyZheng
    password : 125678

    username : AmyZheng
    password : 14789

    3、继承 javax.servlet.http.HttpServlet 类 ,重写 doGet 和 doPost 方法

    测试案例:

    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ThirdServlet extends HttpServlet{
    
        private static final long serialVersionUID = -1117957788110702968L;
    
        @Override
        protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
            System.out.println( "GET" );
            
            request.setCharacterEncoding( "UTF-8" );
            response.setCharacterEncoding( "UTF-8" );
            
            // 接受来自客户端的数据
            String username = request.getParameter( "username" );
            System.out.println( "username : " + username );
            String password = request.getParameter( "password" );
            System.out.println( "password : " + password );
            
            // 向客户端生成响应数据
            response.setContentType( "text/html;charset=UTF-8" );
            PrintWriter w = response.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>你好 , " + username + " !</h1>" );
        }
    
        @Override
        protected void doPost( HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException {
            System.out.println( "POST" );
            
            request.setCharacterEncoding( "UTF-8" );
            response.setCharacterEncoding( "UTF-8" );
            
            // 接受来自客户端的数据
            String username = request.getParameter( "username" );
            System.out.println( "username : " + username );
            String password = request.getParameter( "password" );
            System.out.println( "password : " + password );
            
            // 向客户端生成响应数据
            response.setContentType( "text/html;charset=UTF-8" );
            PrintWriter w = response.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>你好 , " + username + " !</h1>" );
        }
        
        
    
    }

    运行结果如下:

    GET
    username : AmyZheng
    password : 12589
    

     

    POST
    username : AmyZheng
    password : AmyZhengf

    4、继承 javax.servlet.http.HttpServlet 类 ,重写 service( HttpServletRequest , HttpServletResponse ) 方法

    测试案例:

    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ForthServlet extends HttpServlet {
    
        private static final long serialVersionUID = -1403874146599150561L;
    
        @Override
        protected void service( HttpServletRequest request, HttpServletResponse response ) 
                throws ServletException, IOException {
            
            request.setCharacterEncoding( "UTF-8" );
            response.setCharacterEncoding( "UTF-8" );
            
            // 接受来自客户端的数据
            String username = request.getParameter( "username" );
            System.out.println( "username : " + username );
            String password = request.getParameter( "password" );
            System.out.println( "password : " + password );
            
            // 向客户端生成响应数据
            response.setContentType( "text/html;charset=UTF-8" );
            PrintWriter w = response.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>你好 , " + username + " !</h1>" );
            
        }
    
        
    }

    运行结果如下:

     

    username : AmyZheng
    password : AmyZheng1

    username : AmyZheng
    password : AmyZheng2

    Servlet的生命周期

    1、加载和实例化

    • 容器通过反射加载相应的Servlet 类并实例化该类的一个实例。
    • 对Servlet类的加载可能发生在引擎启动时,也可能是用户第一次访问相应的Servlet 时。
    • 容器只为相应的Servlet初始化一个实例(容器里servlet对象只创建一个)。

    2、初始化:调用init() 方法

    • Servlet 第一次被调用时,调用init() 方法一次。
    • 以后除非被reload 或者destory 后重新访问,才会重新调用该方法。
    • 之所以重新调用是因为原有的Servlet 生命周期已结束,一个新的Servlet 生命周期开始。

    3、处理请求:调用service() 方法

    • 业务逻辑一般在该方法中完成,该方法可以被多次调用。
    • 只要有一个用户访问当前Servlet,就会调用该方法(请求一次就服务,一个连接一个线程)。

    4、服务结束:调用destory() 方法

    • 有三种情况会调用destory 方法(只调用一次)

        tomcat将重启
        reload 该webapp
        关闭或重启计算机(Servlet容器也随之关闭)

    测试案例:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>LifeCycleServlet</servlet-name>
            <servlet-class>ecut.lifecycle.LifeCycleServlet</servlet-class>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>LifeCycleServlet</servlet-name>
            <url-pattern>/cycle</url-pattern>
        </servlet-mapping>
        
    </web-app>
    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class LifeCycleServlet  implements Servlet {
        
        static { 
            System.out.println( "加载并初始化LifeCycleServlet类" );
        }
        
        public LifeCycleServlet(){
            System.out.println( "创建 LifeCycleServlet 类的实例" );
        }
    
        @Override
        public void init( ServletConfig config ) throws ServletException {
            System.out.println( "对 LifeCycleServlet 实例进行初始化" );
        }
    
        @Override
        public void service( ServletRequest req , ServletResponse resp ) throws ServletException, IOException {
            System.out.println( "LifeCycleServlet 的实例对外提供服务" );
            
            resp.setCharacterEncoding( "UTF-8" );
            resp.setContentType( "text/html;charset=UTF-8" );
            
            // 向客户端生成响应数据
            PrintWriter w = resp.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>Hello !</h1>" );
            
        } 
        
        @Override
        public void destroy() {
            System.out.println( "准备销毁 LifeCycleServlet 的实例" );
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }

    运行结果如下:

    信息: Server startup in 337 ms
    加载并初始化LifeCycleServlet类
    创建 LifeCycleServlet 类的实例
    对 LifeCycleServlet 实例进行初始化
    LifeCycleServlet 的实例对外提供服务
    LifeCycleServlet 的实例对外提供服务

    如下修改xml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>LifeCycleServlet</servlet-name>
            <servlet-class>ecut.lifecycle.LifeCycleServlet</servlet-class>
            <!-- 当容器 加载当前的WEB应用时就完成对 该 Servlet 的类加载、实例化、初始化操作 -->
            <!-- 数字代表加载优先级,默认值-1访问再加载 -->
            <load-on-startup>0</load-on-startup>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>LifeCycleServlet</servlet-name>
            <url-pattern>/cycle</url-pattern>
        </servlet-mapping>
        
    </web-app>

    指定当web 应用启动时,装载Servlet 的次序

    • 在servlet 标签中使用<load-on-startup> 子标签设置
    • 其中的数字含义如下:

        如果这个数字是正数或0,则容器先加载数值较小的servlet,再加载数值稍大的
        如果是负数或者没有设置,容器将在web 客户端首次访问该servlet 时才加载

    运行结果如下:

    加载并初始化LifeCycleServlet类
    创建 LifeCycleServlet 类的实例
    对 LifeCycleServlet 实例进行初始化
    四月 08, 2018 7:07:00 下午 org.apache.coyote.AbstractProtocol start
    信息: Starting ProtocolHandler ["http-nio-8080"]
    四月 08, 2018 7:07:00 下午 org.apache.coyote.AbstractProtocol start
    信息: Starting ProtocolHandler ["ajp-nio-8009"]
    四月 08, 2018 7:07:00 下午 org.apache.catalina.startup.Catalina start
    信息: Server startup in 346 ms
    LifeCycleServlet 的实例对外提供服务
    LifeCycleServlet 的实例对外提供服务

     ServletConfig

    1、ServletConfig接口:servlet容器在初始化期间将信息传递给servlet的servlet配置对象(用于描述一个Servlet 的配置信息)。

    2、常用方法

    • 获得当前Servlet 实例的名称

        String getServletName()

    • 获得当前Servlet 实例的初始化参数

        String getInitParameter(String name)根据name 获取指定的初始化参数的值,如果name 对应的初始化参数不存在,返回null
        Enumeration getInitParameterNames()返回当前Servlet 实例的所有的初始化参数的名称,注意返回类型是java.util.Enumeration

    • 获得当前Servlet 实例所依赖的应用

        ServletContext getServletContext()

    测试案例:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
    
        <!-- 注册 -->
        <servlet>
            <servlet-name>ConfigurationServlet</servlet-name>
            <servlet-class>ecut.lifecycle.ConfigurationServlet</servlet-class>
            <!-- 指定初始化参数 -->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>content-type</param-name>
                <param-value>text/html</param-value>
            </init-param>
        </servlet>
    
        <!-- 映射(发布) -->
        <servlet-mapping>
            <servlet-name>ConfigurationServlet</servlet-name>
            <url-pattern>/config</url-pattern>
        </servlet-mapping>
        
    </web-app>
    package ecut.lifecycle;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class ConfigurationServlet implements Servlet {
        
        @Override
        public String getServletInfo() {
            return this.config.getServletName() ;
        }
        
        @Override
        public ServletConfig getServletConfig() {
            return this.config ;
        }
        
        private ServletConfig config ;
        
        @Override
        public void init( ServletConfig config ) throws ServletException {
            this.config = config ;
            System.out.println( "初始化" );
            System.out.println( config ); 
            System.out.println( "ServletName : " + config.getServletName() );//web.xm配置文件中的servlet名称
            /*
            String encoding = config.getInitParameter( "encoding" );
            System.out.println( "encoding : " + encoding );
            */
            Enumeration<String> initParamNames = config.getInitParameterNames();
            while( initParamNames.hasMoreElements() ){
                String name = initParamNames.nextElement() ;
                String value = config.getInitParameter( name );
                System.out.println( name + " : " + value );
            } 
        }
    
        @Override
        public void service( ServletRequest req , ServletResponse resp ) throws ServletException, IOException {
            System.out.println( "对外提供服务" );
            
            String ct = config.getInitParameter( "content-type" ) ;
            String en = config.getInitParameter( "encoding" ) ;
            String contentType = ct + ";charset=" + en  ; //  "text/html;charset=UTF-8"
            resp.setContentType( contentType );
            PrintWriter w = resp.getWriter();
            w.println( "<h1 style='text-align:center;color:blue;'>欢迎 !</h1>" );
        } 
        
        @Override
        public void destroy() {
            System.out.println( "销毁" );
        }
    
    }

    配置Servlet 的初始化参数

    • 在servlet 标签中使用init-param 子标签配置

        其中<param-name> 子标签用于设置初始化参数的名称
        <param-value> 子标签用于设置指定参数的值

    • 同一个servlet 中可以使用多个init-param 标签配置多个初始化参数

        使用config.getInitParameter( name ) 可以获取指定名称的参数对应的值
        使用config.getInitParameterNames() 可以获取所有的参数的名称

    运行结果如下:

    初始化
    org.apache.catalina.core.StandardWrapperFacade@4c12c6a
    ServletName : ConfigurationServlet
    content-type : text/html
    encoding : UTF-8
    对外提供服务

    转载请于明显处标明出处

    http://www.cnblogs.com/AmyZheng/p/8742900.html

  • 相关阅读:
    机电传动控制第五周作业
    机电传动控制第四周作业
    机电传动控制 第三周作业
    机电传动控制第二周作业
    机电传动控制 第一周作业
    第一小组咖啡机器人最终结果
    第一组咖啡机器人界面设计1月6日进展
    第一组咖啡机器人界面设计一阶段进展
    实时软件控制第二次作业
    git的学习以及使用
  • 原文地址:https://www.cnblogs.com/AmyZheng/p/8742900.html
Copyright © 2011-2022 走看看