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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值