zoukankan      html  css  js  c++  java
  • [Servlet] 初识Servlet

    目录

    什么是Servlet?

    定义

    Servlet的全称是 Server Applet,顾名思义,就是用 Java 编写的服务器端程序

    Servlet 是一个 Java Web开发标准,狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

     

    功能

    其主要功能在于:交互式地浏览和修改数据,生成动态Web内容。

    Java Web 应用程序中所有的请求-响应都是由 Servlet 来完成的。Servlet 并没有

     

    Java Web 开发的发展历程

    Web 开发技术主要是从静态网页技术动态网页技术的变迁。

    由于本文主要介绍 Java Web 开发技术,所以对其他语言的 Web 技术不做介绍。

    Java Web 开发的大致发展历程如下:静态HTML –> CGI –> Servlet –> JSP

    至于Spring、Struts等著名的框架则是在这些技术基础上的最佳编程实践。

     

    静态网页技术

    早期的Web 开发只能提供静态的 HTML 页面。这样的模式显然存在很多弊端:不利于系统扩展,不利于和用户之间进行交互。于是,有了动态页面技术(如大家熟悉的JSP、ASP、PHP等等)。

     

    动态网页技术

    CGI

    CGI (Common Gateway Interface,公共网关接口)是最重要的 Web 技术之一。它是最早的动态页面技术。

    CGI 是外部应用程序与 Web 服务器之间的接口标准。

    绝大多数的CGI程序被用来解释处理来自表单的输入信息: CGI 允许服务器调用外部程序来处理输入信息,并将相应的输出反馈给浏览器。CGI程序使网页具有交互功能

    注:最流行的CGI 语言是 Perl 和Shell 脚本,但是也可以使用 C、C++ 以及Java 等语言来编写。

    CGI 解决了静态页面不利于交互的问题,但其自身也存在缺陷

    l  需要为每个请求启动一个操作 CGI 程序的系统进程。如果请求频繁,会带来很大的系统开销。

    如果用Java编写 CGI,除了需要为每个请求启动一个系统进程外,还要在进程中启动一个 JVM ,这将十分低效。

    l  需要重复编写处理网络协议的代码,非常耗时。

     

    Servlet

    知道了 Java 编写 CGI 的不足。我们不禁要问,如果有办法可以只运行一个系统进程和一个 JVM ,岂不是能大大减少开销吗?

    Servlet 正是为此应运而生。

    与传统的 CGI 技术相比,Servlet的优势在于:

    l  传统的 CGI 中,每个请求都要启动一个新的进程;而在 Servlet 中,每个请求由一个轻量级的 Java 线程处理。

    l  传统的 CGI 中,如果有 N 个并发的对同一个 CGI程序的请求,则该CGI程序的代码在内存中重复装载了 N 次;而对于 Servlet,处理请求的是 N 个线程,只需要一份 Servlet 类代码。

     

    Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

     

    JSP

    JSP(Java Server Page)是一种实现静态HTML 和动态 HTML 混合编码的技术,它是Servlet API 的一个扩展。

    Servlet 生命周期

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

    Servlet 通过调用 init () 方法进行初始化。

    Servlet 调用 service() 方法来处理客户端的请求。

    Servlet 通过调用 destroy() 方法终止(结束)。

    最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

    如下图:

     

    执行流程为:

    第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。

    Servlet 容器在调用 service() 方法之前加载 Servlet。

    然后 Servlet 容器处理由多个线程产生的多个请求(GET、POST 等类型),每个线程执行一个单一的 Servlet 实例的 service() 方法。service() 会根据请求类型分发到对应的方法中去处理。

     

    init () 方法

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

    Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

    当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

     

    service() 方法

    service() 方法遵循 HTTP 协议标准,负责将 HTTP 请求分发给对应类型的处理方法。

    Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

    每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

    注意:service 方法不需要覆写。

     

    doGet()方法

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

     

    doPost()方法

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

     

    destroy() 方法

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

    在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

     

    Servlet 之 Hello World

    环境设置

    就像任何其他的 Java 程序,需要通过使用 Java 编译器 javac 编译 Servlet,在编译 Servlet 应用程序后,将它部署在配置的环境中以便测试和运行。

    必要条件:

    JDK (Java Development Kit)

    下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

    Tomcat

    下载地址:http://tomcat.apache.org

     

    Hello World 实例

    Servlet 代码

    HelloWorld.java

    package demo;

     

    import java.io.*;

    import javax.servlet.*;

    import javax.servlet.http.*;

     

    publicclass HelloWorld extends HttpServlet {

        privatestaticfinallongserialVersionUID = 1L;

        private String message;

     

        publicvoid init() throws ServletException {

            message = "Hello World ";

        }

     

        publicvoid doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

            // 设置响应内容类型

            response.setContentType("text/html");

     

            // 实际的逻辑是在这里

            PrintWriter out = response.getWriter();

            out.println("<h1>" + message + "</h1>");

        }

     

        publicvoid destroy() {

            // Do nothing

        }

    }

    默认情况下,Servlet 应用程序位于路径 <Tomcat-installation-directory>/webapps/ROOT 下。

    将以上 Servlet 代码编译后产生的class文件放在 <Tomcat 安装目录>/webapps/ROOT/WEB-INF/classes 中。

    注意:需要保持代码的包(package)路径。

    上例中的代码放在demo 包下,classes 下也需要保持路径一致,即 <Tomcat 安装目录>/webapps/ROOT/WEB-INF/classes/demo

     

    Servlet 部署

    下一步,是如何让服务器识别Servlet。

    在web.xml中添加以下内容,然后将web.xml 文件放在 <Tomcat 安装目录>/webapps/ROOT/WEB-INF/web.xml。

    web.xml

    <servlet>

      <servlet-name>HelloWorld</servlet-name>

      <servlet-class>demo.HelloWorld</servlet-class>

    </servlet>

    <servlet-mapping>

      <servlet-name>HelloWorld</servlet-name>

      <url-pattern>/HelloWorld</url-pattern>

    </servlet-mapping>

    (1)<servlet>

    <servlet>标签用于配置 Servlet 类信息。

    <servlet-name>是 Servlet 的标识,必须保证在整个xml 中唯一;

    <servlet-class>是这个 Servlet 对应的类名。

     

    (2)<servlet-mapping>

    <servlet-mapping>标签用于配置Servlet 的访问路径。

    <servlet-name> 需要和<servlet>中的<servlet-name>保持一致;

    <servlet-name>指定访问路径。

     

    做完以上工作,在<Tomcat 安装目录>/bin 目录下执行 startup.bat 或 startup.sh。

    在浏览器中输入网址:http://localhost:8080/HelloWorld

    输出结果:

     

     

    Java Web 目录结构

    Web 程序部署在 Tomcat 的 /webapps 下面。一个 webapps 文件夹可以部署多个不同的 Web 应用,例如 webapps/web1、webapps/web2,访问网址时分别为http://localhost:8080/web1、http://localhost:8080/web2。这两个不同的Web应用分别称为两个Context,路径/web1、/web2也称为上下文路径。

    如果不适用上下文路径,Web 程序需放到webapps/ROOT 下面。ROOT 文件夹下的程序使用http://localhost:8080/ 访问。

    按照Servlet 规范,Web 程序有自己特定的结构,部署时必须按照这样的结构部署。

    文件夹

    描述

    /

    Web 应用根目录

    /WEB-INF/

    Tomcat 会隐藏该文件夹下的所有文件和文件夹,保护他们不能通过浏览器直接访问。

    /WEB-INF/web.xml

    web.xml 文件。Web 程序最主要的配置文件。

    /WEB-INF/classes/

    class 类文件都放在该文件夹下面,包括 Servlet 类。

    /WEB-INF/lib/

    jar 文件都放在该文件夹下面。

     

    参考资料

    http://www.runoob.com/servlet/servlet-tutorial.html

  • 相关阅读:
    [译] 关于CSS中的float和position
    【规范】前端编码规范——注释规范
    【规范】前端编码规范——jquery 规范
    【规范】前端编码规范——javascript 规范
    【规范】javascript 变量命名规则
    如何使用TestFlight进行Beta测试
    i o s 崩溃日志分析
    CocoaPods安装和使用教程
    iOS 程序切换后台
    iOS 百度地图获取当前地理位置
  • 原文地址:https://www.cnblogs.com/aimei/p/12201323.html
Copyright © 2011-2022 走看看