Servlet 是什么?

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:

  • 性能明显更好。
  • Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
  • Servlet 是独立于平台的,因为它们是用 Java 编写的。
  • 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
  • Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。

Servlet 架构

下图显示了 Servlet 在 Web 应用程序中的位置。

Servlet 任务

Servlet 执行以下主要任务:

  • 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
  • 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
  • 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
  • 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
  • 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

servlet容器

Servlet容器(servlet引擎)是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于 MIME的请求,格式化基于MIME的响应。Servlet容器在servlet生命周期内管理的servlet对象。根据Servlet容器工作模式的不同,可以将Servlet容器分为以下三类:

(1)       独立的Servlet容器:

基于java技术的Web服务器:例如tomcat

(2)       进程内的Servlet容器:

Servlet容器由Web服务器插件和Java容器两部分的实现组成。Web服务器插件在某个Web服务器内部地址空间中打开一个 JVM(Java虚拟机),使得Java容器可以在此JVM中加载并运行Servlet。如有客户端调用Servlet的请求到来,插件取得对此请求的控 制并将它传递(使用JNI技术)给Java容器,然后由Java容器将此请求交由Servlet进行处理。进程内的Servlet容器对于单进程、多线程 的服务器非常适合,提供了较高的运行速度,但伸缩性有所不足。例如运行在Apache Web服务器内的Tomcat

(3)       进程外的Servlet容器:

Servlet容器运行于Web服务器之外的地址空间,它也是由Web服务器插件和Java容器两部分的实现组成的。Web服务器插件和Java容 器(在外部JVM中运行)使用IPC机制(通常是TCP/IP)进行通信。当一个调用Servlet的请求到达时,插件取得对此请求的控制并将其传递(使 用IPC机制)给Java容器。进程外Servlet容器对客户请求的响应速度不如进程内的Servlet容器,但进程外容器具有更好的伸缩性和稳定性。

Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

现在让我们详细讨论生命周期的方法。

init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 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 等方法。

下面是该方法的特征:

public void service(ServletRequest request,
ServletResponse response)
throws ServletException, IOException{
}

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

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。

doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}

doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}

destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:

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

架构图

下图显示了一个典型的 Servlet 生命周期方案。

  • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
  • Servlet 容器在调用 service() 方法之前加载 Servlet。
  • 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

创建servlet的三种方式

  •     实现servlet接口   implements Servlet
  •    继承GenericServlet 类   extends  GenericServlet 并实现service()方法
  •    继承HttpServlet 方法 extends  HttpServlet

servlet接口;

package javax.servlet;

import java.io.IOException;

public interface Servlet {
void init(ServletConfig var1) throws ServletException;//用于servlet初始化 ServletConfig getServletConfig();//返回ServletConfig实例,其中包含Servlet初始化和启动参数 void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;//用于服务处理 String getServletInfo();//返回servlet的作者、版本、版权等信息 void destroy();//销毁servlet
}  

GenericServlet类:

是一个抽象类、实现Servlet接口、ServletConfig接口、Serializable接口,实现了Service()并声明成抽象方法,子类必须实现。

package javax.servlet;

import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config; public GenericServlet() {
} public void destroy() {
} public String getInitParameter(String name) {
return this.getServletConfig().getInitParameter(name);
} public Enumeration<String> getInitParameterNames() {
return this.getServletConfig().getInitParameterNames();
} public ServletConfig getServletConfig() {
return this.config;
} public ServletContext getServletContext() {
return this.getServletConfig().getServletContext();
} public String getServletInfo() {
return "";
} public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
} public void init() throws ServletException {
} public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
} public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
} public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; public String getServletName() {
return this.config.getServletName();
}
}

HttpServlet类:

是一个抽象类,继承了抽象类GenericServlet,使用了HttpServletRequest 和 HttpServletResponse进行封装

abstract class HttpServlet extends GenericServlet{

   //HttpServlet中的service()
protected void service(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse){
//该方法通过httpServletRequest.getMethod()判断请求类型调用doGet() doPost()
}
// HttpServletRequest接口:提供基于HTTP协议的请求视图。该接口中定义的方法用于获取HTTP请求头信息。Cookie信息等。
// HttpServletResponse接口:提供基于HTTP协议的响应视图。该接口中定义的方法用于设置HTTP请求头信息。Cookie信息等
//必须实现父类的service()方法
public void service(ServletRequest servletRequest,ServletResponse servletResponse){
HttpServletRequest request;
HttpServletResponse response;
try{
request=(HttpServletRequest)servletRequest;
response=(HttpServletResponse)servletResponse;
}catch(ClassCastException){
throw new ServletException("non-http request or response");
}
//调用service()方法
this.service(request,response);
}
}

Servlet 部署

通过web.xml来部署:Servlet01

<web-app>
<servlet>
<servlet-name>Servlet01</servlet-name>
  #完全限定名=包名+类名
<servlet-class>cn.xy.servlet.Servlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app> 
 

通过注解方式来部署Servlet01

@WebServlet(name = "Servlet01",urlPatterns = {"/hello"})
或者
@WebServlet("/hello")

servlet 浏览器访问路径配置有个小问题:

1、java 类里的注解 —— @WebServlet("/HelloServlet") 对应浏览器路径:

http://localhost:8080/TomcatTest/HelloServlet
 

2、配置文件(web.xml)里对应的浏览器访问路径:

http://localhost:8080/TomcatTest/TomcatTest/HelloServlet

这两种配一个就好了,不然路径重名的话反而会让tomcat启动不了。

例如这样就启动不了:

修改 web.xml :

<url-pattern>/HelloServlet</url-pattern>

修改后,web.xml 和 java 类的注解,对应路径都是:

http://localhost:8080/TomcatTest/HelloServlet

导致

命名的 servlet[HelloServlet]和 [com.runoob.test.HelloServlet] 都被映射到 URL 模式 [/ HelloServlet] 这是不允许的。


解决方法

注解去掉或者保留注解进入web.xml将映射删除既可以。

Servlet 映射的类型和顺序:

1、  精确映射 /test/index.jsp 请求路径必须是/test/index.jsp

2、  路径映射 /test/*        请求路径可能是/test/index.html或者/test/index.jsp

3、  扩展映射 *.jsp                    请求路径后缀带.jsp都行

4、  默认映射 如果无法匹配的Servlet,则将请求转发给默认的Servlet;如果没有默认的Servlet,则返回404

初始化参数:

<web-app>
<context-param>
<!--全局初始化参数-->
<param-name>name</param-name>
<param-value>ayao</param-value>
</context-param>
</web-app>
通过ServletContext的getInitParamter()来获取全局初始化参数
<web-app>
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>cn.xy.servlet.Servlet01</servlet-class>
<init-param>
<!--局部servlet初始化参数-->
<param-name>name</param-name>
<param-value>ayao</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
通过ServletConfig接口中的getInitParamter()在init()方法中获取初始化参数

java 之 servlet简介的更多相关文章

  1. java Web servlet简介及其生命周期

    Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容. 我们可 ...

  2. Servlet基础(一) Servlet简介 关键API介绍及结合源码讲解

    Servlet基础(一) Servlet基础和关键的API介绍 Servlet简介 Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中. Servlet容器负责Servl ...

  3. Servlet简介与Servlet和HttpServlet运行的流程

    1.Servlet      [1] Servlet简介         > Server + let         > 意为:运行在服务器端的小程序.         > Ser ...

  4. JavaEE:Servlet简介及ServletConfig、ServletContext

    Servlet简介 1.Servlet是sun公司提供的一门用于开发动态web资源的技术*静态web资源:固定数据文件*动态web资源:通过程序动态生成数据文件2.Servlet技术基于Request ...

  5. Servlet简介及使用

    javaweb学习总结(五)——Servlet开发(一) 一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口 ...

  6. servlet简介及生命周期

    Servlet 简介 Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上 ...

  7. (一)Servlet简介

    相关名词解释 HTML:Hyper Text Markup Language,超文本标记语言 HTTP:Hyper Text Transfer Protocol,超文本传输协议 URL:Uniform ...

  8. 【Servlet】(1)Servlet简介、Servlet底层原理、Servlet实现方式、Servlet生命周期

    一.Servlet简介 1.Servlet定义: Servlet(Server Applet)是Java Servlet的简称,是为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交 ...

  9. Java基础——Servlet(一)

    在学习Servlet之前,需要首先学习一些关联性的知识. 一.动态网页程序 动态网页:它是网页中的偏功能性的部分也是最重要的部分.它不是我们平时所看见的页面特效,展示的效果.而是,一种交互行为.比如, ...

随机推荐

  1. Java 程序该怎么优化?(技巧篇)

    搬砖者:为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了? 面试官:简单谈谈 Java 程序性能优化? 1. 字符串处理优化,乃优化之源. 研发过程中,String 的 API 用的应该是 ...

  2. 1000行MySQL学习笔记,不怕你不会,就怕你不学!

    Windows服务 -- 启动MySQL net start mysql-- 创建Windows服务 sc create mysql binPath= mysqld_bin_path(注意:等号与值之

  3. ASP.NET Core WEB API 使用element-ui文件上传组件el-upload执行手动文件文件,并在文件上传后清空文件

    前言: 从开始学习Vue到使用element-ui-admin已经有将近快两年的时间了,在之前的开发中使用element-ui上传组件el-upload都是直接使用文件选取后立即选择上传,今天刚好做了 ...

  4. Vue点击当前元素添加class 去掉兄弟的class

    <div id="app"> <ul> <li v-for="(todo, index) in todos" v-on:click ...

  5. PTA数据结构与算法题目集(中文) 7-26

    PTA数据结构与算法题目集(中文)  7-26 7-26 Windows消息队列 (25 分)   消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生, ...

  6. Shell:Day10

    shell脚本:明白一点:shell脚本本身是一个工具 在写shell脚本之前,就要明白:这个功能能到底如何实现? curl 访问文件源代码,查看网站状态: 才能通过shell(bash)所提供的逻辑 ...

  7. CF632(div.2)C. Eugene and an array

    https://codeforces.ml/contest/1333/problem/C 大概题意是规定和为0的数组为不合格数组,询问给定数组中共有多少个合格子数组. 解题 子数组的数量 一个长度为 ...

  8. 基于 mpvue 框架的小程序选择控件,支持单列,多列,联动

    最近在学着写mpvue小程序,在做选择控件时候遇到了点问题,按照微信小程序方法picker,很不方便! 在网上搜到一个很好用的组件下面给大家分享: 组件说明文档链接:https://go.ctolib ...

  9. matplotlib 显示最后n条数据(可用于实时更新)

    2020-04-16 14:05:01 --Edit by yangray 按横轴刻度的种类不同,分为数值类刻度和日期类刻度. 数值类刻度 需求:x轴数据间隔为2,显示最后24条数据. #!/usr/ ...

  10. python3(三十一)metaclass

    """ """ __author__ = 'shaozhiqi' # 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而 ...