Servlet(1)-Servlet简介、简单的Servlet示例

Java Servlet是运行在服务器或应用服务器上的程序,它是作为来自Web浏览器的请求或其他HTTP客户端的请求与HTTP应用服务器的数据库或应用程序的中间层。使用Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或其他源的记录,还可以动态创建网页。

Servlet架构

下图展示了Servlet在Web应用程序中的位置:


Servlet架构

Servlet任务

  • 读取客户端(浏览器)发送的显式数据。包括表单数据等等。
  • 读取客户端(浏览器)发送的隐式的HTTP请求数据。包括cookies等等。
  • 处理数据并生成结果。需要访问数据库。
  • 发送显式的数据(即文档)到客户端(浏览器)。该文档格式可以是多种多样的,包括文本文件(HTML文件、XML文件等)、二进制文件(图像)等。
  • 发送隐式的HTTP响应到HTTP客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如HTML)、设置cookies和缓存参数,以及其他类似的参数。

使用Servlet

1、创建Servlet的三种方式
(1)实现javax.servlet.Servlet接口。
(2)继承javax.servlet.GenericServlet类
(3)继承javax.servlet.http.HttpServlet类

我们在日常开发中一般会使用第三种方法来进行Servlet的创建,前两种方法理解即可.。
注意:创建Servlet文件后,需要在web.xml文件中完成Servlet配置,才可以使用。

2、配置Servlet的两种方式

(1)使用web.xml文件配置Servlet。例如,我有一个名为ServletDemo的Servlet,主要将它配置到服务器进行运行,可以按照下面的代码进行配置web.xml文件:

<servlet>
    <!-- 声明Servlet名称和所在的类 -->
    <servlet-name>ServletDemo</servlet-name>
    <servlet-class>cn.tender.servlet.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
    <!-- <servlet-mapping>中<servlet-name>标签规定的<Servlet>名应该和<servlet>中的一致 -->
    <servlet-name>ServletDemo</servlet-name>
    <!-- 这是浏览器发送请求的时候访问的Servlet名称,可以按照自己的意愿进行配置名称 -->
    <url-pattern>/ServletDemo</url-pattern>
</servlet-mapping>

(2)使用注解进行Servlet配置(高版本后默认使用此方法):
当我们去创建一个Servlet时会默认继承HttpServlet类,会使用注解方式进行配置Servlet:

// 这种方式配置的效果与第一种一致
@WebServlet("/HelloServlet")

注意:两种配置方式不能同时使用,即配置了web.xml就不能使用注解,使用了注解也就不能使用web.xml配置了。

Servlet相关知识

1、Servlet容器装载Servlet的时刻:
(1)Servlet容器启动后会自动装载某些Servlet;
(2)在Servlet容器启动后,客户端首次向Servlet容器发送请求;
(3)Servlet文件被更新后,重新装载Servlet。
在默认情况下,当Web客户第一次请求访问某个Servlet时,Web容器会创建这个Servlet的实例。
当设置了web.xml中<servlet>的子元素<load-on-startup>后,Servlet容器在启动Web应用时,将按照指定顺序创建并初始化这个Servlet。设置的数值大于0即可。例如:

<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.langsin.servlet.HelloServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

2、Servlet的生命周期:
先看与Servlet生命周期有关的三个方法:init(), service(), destroy(). Servlet生命周期可被定义为从创建直到毁灭的整个过程。以下是三个方法分别对应的Servlet过程:

  • init():Servlet进行初始化;
  • service():Servlet处理客户端的请求;
  • destroy():Servlet结束,释放资源;

在调用destroy()方法后,Servlet由JVM的垃圾回首器进行垃圾回收。

现在我们来详细讨论Servlet生命周期的方法:

init()方法:
     init()方法被设计成只调用一次。它在第一次创建Servlet时被调用,在后续处理每个人Http请求的时候,不会再调用,因此,它只用于Servlet的一次性初始化。
     Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化在Servlet生命周期中init()方法只被调用一次。
     当用户调用一个Servlet时,Servlet容器就会创建一个Servlet实例,每一个用户请求都会产生一个新的线程,适当的时候移交给doGet()doPost()方法。init()方法简单的创建或加载一些数据,这些数据将会被用在Servlet的整个生命周期。
     init()方法的定义如下:

public void init() throws ServletException {
  // 初始化代码...
}

service()方法:
     service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
     每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用doGet()doPost()doPut()doDelete() 等方法。
     service()的定义如下:

public void service(ServletRequest request, ServletResponse response) 
    throws ServletException, IOException{
// service()代码...
}

      service()方法由容器调用,service()方法在适当的时候调用doGet()doPost()doPut()doDelete() 等方法,所以,我们不需要对service()方法做任何动作,只需要根据客户端的请求类型重写doGet()doPost()方法即可。

destroy()方法:
      destroy()方法只会被调用一次,在Servlet生命周期结束时被调用。destroy()方法可以让Servlet关闭数据库连接、停止后台、把cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
      在调用destroy()方法之后,Servlet对象被标记为垃圾回收。
      destroy()方法的定义如下所示:

public void destroy() {
    // 终止化代码...
  }

     在首次访问某个Servlet时,init()方法会被执行,而且也会执行service()方法。再次访问时,只会执行service()方法,不再执行init()方法。在关闭Web容器时会调用destroy()方法。

继承HttpServlet类创建Servlet

1、HttpServlet概述
     继承HttpServlet创建Servlet的方法是我们开发中最常用的一种方式。它与HTTP协议有关,HTTP协议中有两种常用的请求方式,getpost。而我们使用的HttpServlet时会获得这两种请求方式产生的请求和响应对象,通过这两个对象完成处理与响应。
     HttpServlet类中提供了service(HttpServletRequest request, HttpServletResponse response)方法,这个方法是HttpServlet自己的方法,不是从Servlet类中继承来的。在HttpServletservice(ServletRequest, ServletResponse)方法中会把ServletRequestServletResponse强转成HttpServletResponseHttpServletResponse,然后调用service(HttpServletRequest, HttpServletResponse)方法,这说明子类可以去覆盖service(HttpServletRequest,HttpServletResponse)方法即可,这就不用自己去强转请求和响应对象了。
     在HttpServletservice(HttpServletRequest, HttpServletResponse)方法会去判断当前请求是GET还是POST,如果是GET请求,那么会去调用本类的doGet()方法,如果是POST请求会去调用doPost()方法,这说明我们在子类中去覆盖doGet()doPost()方法即可。
     以下是doGet()doPost()方法的原型:

protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    //测试代码
    }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

注意:doPost()方法中调用了doGet()方法,因此在实现两个方法时,如果代码逻辑一致,只写一遍代码即可。

2、创建HttpServlet实例
(1)创建ServletDemo类,实现HttpServlet接口:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 用于测试Servlet的Demo类
 * @author mTender
 */
public class ServletDemo extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public ServletDemo() {
        
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 使用HttpServletResponse对象设置文档的content-type类型
        resp.setContentType("text/html;charset=utf-8");
        // 使用HttpServletResponse对象向jsp文件中写入字符
        resp.getWriter().append("welcome");
    }

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

(2)使用注解或者配置web.xml,这里采用的是配置web.xml文件的形式:

<servlet>
    <servlet-name>ServletDemo</servlet-name>
    <servlet-class>com.demo.ServletDemo</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo</servlet-name>
    <url-pattern>/Servlet.do</url-pattern>
  </servlet-mapping>

(3)开启服务器,访问ServletDemo,网页中会出现下图所示效果:


Servlet访问成功

3、简单JSP&Servlet实例
假设我们现在向Servlet提交一个表单,表单包括我们的用户名和密码,我们需要从JSP页面获取数据,并将用户名和密码在Eclipse的控制台打印出来。
(1)创建JSP页面:

<!-- 简单的写了一个表单,包括用户名输入和用户密码输入,没有写样式 -->
<body>
    <form action="/WebF18/Servlet.do" method="post">
        用户名:<input type="text" name="UserName"><br>
        密&nbsp;码:<input type="password" name="password"><br>
        <input type="submit" value="提交">
    </form>
</body>

(2)创建ServletDemo

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 用于测试Servlet的Demo类
 * @author mTender
 */
public class ServletDemo extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public ServletDemo() {
        
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 使用HttpServletResponse对象设置文档的content-type类型
        resp.setContentType("text/html;charset=utf-8");
        
        req.setCharacterEncoding("utf-8");
        // 获取前端页面提交过来的数据
        String username = req.getParameter("UserName");
        String password = req.getParameter("password");
        System.out.println("Username:" + username + " password:" + password);
        
    }

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

(3)配置ServletDemo类,配置方式和2、Servlet实例中配置方式相同,这里不再赘述;
(4)我在JSP表单的输入框内填入的用户名是:mTender;密码是:123456,点击提交,在Eclipse的控制台上可以看到以下输出:

用户信息提交成功

     我们在获取用户信息完成之后,就可以对用户信息进行校验或者加工,例如:我们可以校验用户数据是否符合我们要求用户遵守的信息标准,也可以在这个时候给用户的密码进行加密(目前比较常用的用户密码加密方法是MD5码加密)等一系列的操作。


     刚刚开始学习Java Web,还基本上是个小白,文章中的错误欢迎大家指正!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容