第一个Servlet程序

第一个Servlet程序

Servlet前置知识 中有对Servlet的基本介绍。

Sun公司定义了一套专门用于Servlet程序的Java类和接口,这些类和接口提供了Servlet程序开发中所涉及的各种功能,他们统称为Servlet API(Servlet Application Programming Interface)。

Servlet的开发工具包的目录为<Tomcat安装目录>/lib/servlet-api.jar,此处Tomcat版本为8.0。Servlet API帮助文档在线地址:http://tomcat.apache.org/tomcat-8.5-doc/servletapi/index.html

Servlet程序的编写

一个Servlet程序就是运行在Web服务器端的特殊Java类,这个特俗的Java类必须实现javax.servlet.Servlet接口,Servlet接口定义了Servlet引擎与Servlet程序之间通信的协议约定。Servlet API本身提供了一个实现了Servlet接口的Servlet类。即javax.servlet.GenericServlet,这个类实现了Servlet程序的基本特征和功能。

Servlet API还提供了一个继承自javax.servlet.GenericServlet的专用于HTTP协议的HttpServlet类,为了更方便的使用HTTP协议,我们自己的Servlet直接继承HttpServlet类即可,然后根据我们的请求类型覆写doGet或doPost方法即可(没有必要覆写service方法,它本身就根据请求类型将请求分发给对应的doMethod方法)。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

因为是覆写,记得删掉继承的代码:

super.doGet(req, resp);

HttpServletRequest封装了Http的请求消息,HttpServletResponse的getWriter方法可以获得一个文本输出流对象,通过这个流对象写入的数据将会作为Http响应消息的实体内容部分发送给客户端。

编译Servlet程序

我们在命令行下编译上面的Servlet程序:

javac HelloServlet.java

一般情况下会编译错误,提示找不到类,那是因为我们没有在环境变量中配置相关jar包。


vim ~/.bash_profile

 # set classpath
 export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home
 export CATALINA_HOME=/Users/oyty/Documents/tomcat
 export SERVLET_JAR=$CATALINA_HOME/lib/servlet-api.jar
 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$SERVLET_JAR

source ~/.bash_profile

重新编译后得到HttpServlet.class文件。

Servlet的注册和运行

Servlet程序必须通过Web服务器和Servlet引擎来启动运行,对此,Servlet的存储有一定的规范。编译后的class文件需要存储在<Web应用程序目录>/Web-INF/classes/目录中,另外,Servlet程序也必须在和Web-INF的同级目录下的web.xml文件中注册,才可以被Servlet引擎加载和被外界访问。

注册和映射Servlet

web.xml文件的模板可以在tomcat例子程序中找到。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">
  <display-name>Welcome to Tomcat</display-name>

  <description>
     Welcome to Tomcat
  </description>

  <servlet>
    <servlet-name>Hello</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Hello</servlet-name>
    <url-pattern>/hello/helloservlet</url-pattern>
  </servlet-mapping>

</web-app>

一个<servlet>用于注册一个Servlet,<servlet-name>为Servlet的注册名,<servlet-class>为Servlet的完整类名。完整类名是什么意思呢?当前的例子中,HttpServlet类不在任何包下,所以这里配置直接是类名,如果HttpServlet的包名为com.hello,那么此处注册名为com.hello.HelloServlet,编译后的HttpServlet.class文件也存储在classes目录下的根据包名生成的目录下:.../Web_INF/classed/com/hello/HelloServlet.class

一个<servlet-mapping>用于映射一个Servlet,<servlet-name>需要与前面注册名相同,<url-pattern>需要以/开头,表示Web程序的根目录,后面可随意指定,地址映射可以使用*通配符,须记住*.扩展名的优先级最低。

运行第一个Servlet程序

一切配置好后,重启Tomcat,在浏览器中输入http://localhost:8080/hello/helloservlet,会得到doGet方法中的返回信息

Servlet生命周期

当servlet被部署在应用服务器中(应用服务器中用于管理Java组件的部分被抽象成为容器)以后,由容器控制servlet的生命周期。除非特殊指定,否则在容器启动的时候,servlet是不会被加载的,servlet只会在第一次请求的时候被加载和实例化。servlet一旦被加载,一般不会从容器中删除,直至应用服务器关闭或重新启动。但当容器做内存回收动作时,servlet有可能被删除。也正是因为这个原因,第一次访问servlet所用的时间要大大多于以后访问所用的时间。

servlet在服务器的运行生命周期为,在第一次请求(或其实体被内存垃圾回收后再被访问)时被加载并执行一次初始化方法,跟着执行正式运行方法,之后会被常驻并每次被请求时直接执行正式运行方法,直到服务器关闭或被清理时执行一次销毁方法后实体销毁。

参考:
张孝祥《深入体验Java Web开发内幕-核心基础》

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

推荐阅读更多精彩内容

  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,366评论 1 92
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,218评论 11 349
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 本文包括: Servlet简介关于Servlet的一些类 Servlet生命周期 ServletConfig获得初...
    廖少少阅读 3,845评论 1 67
  • 自信,是你有足够的准备时,应对事发的状态 没有自信,即使你有足够的知识储备,却没有经常训练从脑中迅速准确提取信息的...
    驭临风阅读 304评论 0 1