Servlet 学习(二)

本文介绍Servlet的四种实现方式,包括实现Servlet接口、继承GenericServlet、继承HttpServlet等,并详细解析了Servlet的生命周期及其配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

伴随着如今计算机技术在各行各业日益广泛和深入的应用,电子商务的概念早已深入人心,电子商务的应用也越来越广泛,对企业的影响也越来越大。现在,电子商务的应用几乎渗透到各行各业。企业可以通过电子商务寻找客源、推广产品、销售商品、产品采购,寻求战略合作伙伴等等。电子商务与传统企业在生产、流通、消费等环节的深度融合,改变了传统企业的经营模式和营销模式,让企业在清楚地了解每个客户的个性化需求,作出相应的企业利润最大化的策略,同时也可以改善客户关系,改善企业的形象,提高了企业的资源配置和运营管理水平。 其中网上商城就是电子商务应用的一个发展的潮流。网上商城不但让消费者购物更加方便,而且能为企业带来很多好处。 本论文研究一种基于springmvc、spring、mabatis简称ssm三大框架设计的javaee网上服饰商城系统。系统的前台显示效果采用了jquery,bootstrap技术,前后台交互使用了ajax和json。本系统采用的是B/S软件架构,使用的开发工具是eclipse,使用的数据库是mysql。其开发流程经历了开发背景,目的和意义的分析以及系统的分析和设计。该系统重点分析了用户的需求以及实现方式,使用rose设计了面向对象分析的用例图,时序图和活动图。本系统主要分为前台会员顾客管理模块和后台管理员模块。前台会员顾客操作主要有:商品浏览,会员注册,会员登录,会员信息修改,购物车管理,购买商品等功能模块。后台管理主要有:订单管理,商品管理,会员管理,系统设置四个功能模块。因为系统采用MVC模式设计思想,使得系统的可移植性非常强,只需修改配置文件就能在在不同服务器上运行。 关键字:电子商务、javaee、jQuery、ssm、B/s、mvc、mysql、服饰商城系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值