Java后台开发——Servlet篇

参考资料

《JSP从零开始》—— 刘鑫
Servlet官方文档
孤傲苍狼 博客园

前言

本人菜鸟,入IT只为当鼓励师。本编文章对 Servlet 作简要介绍,其中包括讲解:Servlet是什么、Servlet的功能、Servlet的生命周期、HttpServlet对象。

一、Servlet是什么

  • 一门用于开发动态web资源的技术,由sun公司提供。
  • java类编写的服务端应用程序
  • Servlet程序是由web服务器(tomcat等)调用的

说简单点,就是Sun公司开发出了一套API(java.servletjava.sevlet.http等),你可以用这些api开发Java程序,用来处理客户端请求,并控制输出的响应(向客户端浏览器输出的内容)。

Java后台开发——Servlet篇_第1张图片
servlet api

总结起来,你只需要:
① 编写一个实现了servlet接口的java类;
② 把开发好的Java类部署到web服务器中。

所以,有时我们也称实现了servlet接口的java程序为Servlet。

二、Servlet的功能

  • 对客户端发送的数据进行读取和拦截
    客户端发送一个请求会携带数据(url中的参数,页面表单提交,ajax请求),当一个Servlet接收到请求,java Servlet中的类可以通过提供的方法获得这些参数(request.getParameterName(name)等)。因此Servlet可以起拦截作用,在请求前先判断该客户端能否做出这些请求 ,若能再从服务器得到请求的资源。
    Java后台开发——Servlet篇_第2张图片
    图例
  • 读取客户端的请求的隐含数据
    客户端请求的数据可分为:隐含数据,显式数据。
    隐含数据:不存在于URL中,而存在于请求的来源,缓存数据(cookie)、客户端类型(在header中)。
    显式数据:用户可见的,表单数据(来自于form)或URL参数。
    Servlet都可处理。

  • 运行结果或者生成结果
    一个Web应用程序对客户端发出的请求做出响应时,一般有很多中间过程才能得到结果,Servlet就担起了这个中间角色功能。(后面深入学习会知道,javaweb开发中的控制层是由Servlet实现的,就是常说的MVC中的C)


    Java后台开发——Servlet篇_第3张图片
    图例
  • 发送响应的数据
    Servlet对客户端做出响应并经过处理得出结果后,会对客户端发送响应的数据,让客户端获取请求的结果数据。

三、Servlet的生命周期

Servlet的生命周期包含3个阶段:

1. 初始化阶段

当web服务器收到客户端对某一url地址的访问请求时,若该url配置了对应的Servlet程序,则开始该阶段。


Java后台开发——Servlet篇_第4张图片
检查请求url是否有对应的Servlet程序
  • web服务器检查是否已经装载并创建了该Servlet的实例对象。如果是,则跳过初始化阶段,否则进入下一步。
  • 装载(由Servlet容器装载一个Servlet类,把它装在到Java内存中)并创建该Servlet的一个实例对象,与 web.xml 中的配置对应起来。
  • 调用Servlet实例对象的 init() 方法。在整个Servlet生命周期中,init() 方法只被调用一次。
    Java后台开发——Servlet篇_第5张图片
    步骤图示

    首次访问的两个注意点

2. 运行阶段

该阶段实际响应客户端的请求。

  • Servlet创建 HttpServletRequestHttpServletResponse 对象,前者与HTTP协议有关,后者与协议无关。
  • 调用 service(HttpServletRequest request, HttpServletResponse response) 方法,该方法通过request对象获得请求对象的信息并加以处理,再由response对象给客户端做出响应。
Java后台开发——Servlet篇_第6张图片
每当有请求时,服务端的一系列动作
Java后台开发——Servlet篇_第7张图片
调用 service() 方法,可访问请求和响应对象
Java后台开发——Servlet篇_第8张图片
运用request对象读取请求信息,处理后运用response对象写入响应信息
Java后台开发——Servlet篇_第9张图片
service() 方法返回
Java后台开发——Servlet篇_第10张图片
服务器读取响应信息
Java后台开发——Servlet篇_第11张图片
服务器发出http响应,将数据返回到客户端浏览器中

3. 消亡阶段

  • web应用程序被停止或重新启动之前,Servlet容器将调用 destroy() 方法,对Servlet对象进行销毁,释放其所占资源。在整个Servlet生命周期中,destory() 方法只被调用一次。

四、创建Servlet的步骤

  1. 引入相应的包,如:java.servletjava.servlet.http 包,两个包的区别是前者与协议无关,后者与HTTP协议相关。
  2. 创建一个扩展类,如本例中的 HelloServlet,并继承 HttpServlet 类。(一般的,HttpServlet 类封装了很多基于HTTP协议下的Servlet功能,基本够用,若自己想开发一个协议可继承 GenericServlet 类)
  3. override doGet()doPost() 方法,doGet() 响应get请求,doPost() 响应Post请求。或者可以override service()方法,对所有请求统一处理。欲详细了解 service()doGet()doPost()等方法,请看:五、关于 Servlet、HttpServlet、GenericServlet
代码示例:
package com.javaweb.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/* 用注入声明的方式表示这是一个 Servlet 类,不用在web.xml中配置 Servlet */
@WebServlet (
    urlPatterns = { "/HelloServlet" },
    name = " helloServlet "
)

// 继承HttpServlet类
public class HelloServlet extends HttpServlet {

    // 序列化,可以自动生成或者自行定义
    private static final long serialVersionUID = 1L;

    // 一、初始化阶段的 init() 方法
    public void init() throws ServletException {
    System.out.println("初始化 init 方法");
    }

    // 过程二执行的方法有一定的顺序与条件,详细请看: 五、关于 Servlet、HttpServlet、GenericServlet
    // 二、调用 public service 方法
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        System.out.println("调用 public service 方法");

        // 设定页面的MINE类型和字符集
        response.setContentType("text/html;charset=utf-8");
    
        // 输出响应
        PrintWriter out = response.getWriter();
        out.println("收到 service 请求");
    }

    // 二、调用 protected service 方法
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        System.out.println("调用 protected service 方法");
    }

    // 二、调用 doGet() 方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    // 二、调用 doPost() 方法
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("调用 doPost() 方法"); 
    
        // 设定页面的MINE类型和字符集
        response.setContentType("text/html;charset=utf-8");
    
        // 输出响应
        PrintWriter out = response.getWriter();
        out.println("收到 HelloServlet doPost() 请求");
    }

    // 三、消亡阶段的 destory() 方法
    public void destory() {
        System.out.println("调用 destory() 方法");
    }
 } 

五、关于 Servlet、HttpServlet、GenericServlet

Servlet 来自于 javax.servlet.Servlet
HttpServlet 来自于 javax.servlet.http.HttpServlet
GenericServlet 来自于 javax.servlet.GenericServlet

1. Servlet

servlet 是一个接口,如果实现这个接口,那么就必须实现接口里面定义的所有方法。一般开发不会去自己实现该接口,它只提供了一种规范,供 开发者 自己来编写相关的实现


Java后台开发——Servlet篇_第12张图片
api中对 Servlet 接口的说明
  • 可以看出,Servlet接口提供了5个必须实现的方法


    Java后台开发——Servlet篇_第13张图片
    Servlet 接口中的方法

2. GenericServlet

  • GenericServlet 定义了一个通用的,无关协议的Servlet。如果要在Web应用中使用Http进行Servlet通信,请扩展 HttpServlet(即继承 HttpServlet
  • 在《JSP从零开始》的第100—101页有GenericServlet类的部分源代码,读者有兴趣可研究一下


    Java后台开发——Servlet篇_第14张图片
    api中对 GenericServlet 抽象类的说明
  • 下面是 GenericServlet中的方法
    Java后台开发——Servlet篇_第15张图片
    GenericServlet 类中的方法

3. HttpServlet

HttpServlet 是一个抽象类,它继承了 GenericServlet 抽象类,而 GenericServlet 类实现了 Servlet 接口,所以HttpServlet 类也就默认实现了 Servlet 接口。默认实现规范而实用,开发web端的servlet程序,一般我们只需继承 HttpServlet 类就可以了

Java后台开发——Servlet篇_第16张图片
api中对 HttpServlet 抽象类的说明

  • 创建 HttpServlet 的步骤:
    ①继承 HttpServlet 抽象类;
    ②覆盖 HttpServlet 的部分方法,如覆盖 doGet()doPost() 方法;
    ③获取HTTP请求信息。通过 HttpServletRequest 对象来检索HTML表单所提交的数据或URL上的查询字符串;
    ④生成HTTP响应结果。通过 HttpServletResponse 对象生成响应结果,它有个 getWriter() 方法,该方法返回一个 PrintWriter 对象。

  • 它总共有10个方法,其中实现了:


    Java后台开发——Servlet篇_第17张图片
    HttpServlet 中的方法

① 2个重载的 service() 方法

  • 在servlet中默认情况下,无论是get还是post 提交过来 都会经过service()方法来处理,然后转向到doGet()doPost()方法,所以默认情况(没有重写service方法)下,service()是用来转向的。
  • 如果你在自己的servlet类中覆盖了service()方法,那么service()就不是用来转向了,而是用来处理业务,这时不论客户端是用post还是get来请求此servlet,都会执行service()方法也只能执行servlet()方法,不会去执行doPost()doGet()方法。
    Java后台开发——Servlet篇_第18张图片
    各个方法的执行顺序和条件

② doGet(),doPost(),doOptions(),doTrace(),doDelete(),doHead(), doPut() 这7个方法

  • 最常用的还是doGet()doPost(),但一般来说我们是用不到doGet()方法的。doGet()方法提交表单时会在url后边显示提交内容,并不安全。而且doGet()方法只能提交256个字符(1024字节),而doPost()没有限制,因为get方式数据的传输载体是URL(提交方式能form,也可以是任意的URL链接),而POST是HTTP头键值对(只能以form方式提交)。通常我们使用的都是doPost()方法,你只要在servlet中让这两个方法互相调用就行了。

③ getLastModified(HttpServletRequest req) 方法

  • 传入参数为一个HttpServletRequest对象
  • 返回一个数值,该值为从 1970年1月1日HttpServletRequest对象最近一次修改的那个时刻 走过的毫秒数。

最后,分享我用PowerDesigner创建的面向对象模型的关系图来说明三者的关联:


Java后台开发——Servlet篇_第19张图片
面向对象模型图
  • 对PowerDesigner有兴趣的读者可以看该文集中的:PowerDesigner入门篇,可初步了解一下这个软件的使用。

你可能感兴趣的:(Java后台开发——Servlet篇)