servlet入门
开发步骤:
- 编写一个java类,实现servlet接口
- 把开发好的java类部署到web服务器
API文档
生命周期相关方法(life-cycle methods)
Servlet的生命周期通过java.servlet.Servlet
接口中的init()
、service()
、和destroy()
方法表示。Servlet的生命周期有四个阶段:加载并实例化、初始化、请求处理、销毁。(见文末【参考链接】)
手动编写第一个servlet
1.在tomcat中新建一个web应用hello
,在web应用中新建一个WEB-INF/classes
目录
2.在classes
目录新建一个FirstServlet
1 | package org.iot; |
3.编译,javac -cp %CATALINA_HOME%/lib/servlet-api.jar -d . FirstServlet.java
,命令行手动编译参考这里
4.在WEB-INF
目录中新建一个web.xml
文件,配置servlet的对外访问路径
5.启动tomcat访问
servlet的调用过程和生命周期
时序图
servlet开发的一些细节
- 标签:
<servlet>
包含<servlet-name>
和<servlet-class>
;<servlet-mapping>
包含<servlet-name>
和<url-pattern>
- 映射:
web.xml
中一个<servlet>
可对应多个<servlet-mapping>
- 通配符:
<servlet-mapping>
的<url-pattern>
可以使用通配符,两种固定格式:*.扩展名
;以/
开头,以/*
结尾
- 对象:servlet由servlet引擎调用,不能独立运行。客户端多次请求,服务器只创建一个servlet实例,之后驻留内存中继续服务直至web容器退出才销毁它。
- 请求:服务器针对客户端的每一次请求都会创建新的
request
和response
对象(它们的生命周期很短),传给service
方法。 - 加载:servlet实例的创建和
init
方法的调用是在第一次请求时,而非服务器启动时,除非在<servlet>
标签配置<load-on-start-up>
,数字越小优先级越高 - 缺省:映射路径为正斜杠
/
,则为当前web应用的缺省servlet,不匹配的都交给缺省 - 线程安全:访问同一资源会引发线程安全问题;
SingleThreadModel
标记接口(已弃用) - ServletConfig:在
<servlet>
标签配置<init-param>
,通过getServletConfig
方法获得配置。可配置输出字符集,读哪个配置文件等等。 - ServletContext:代表当前web应用,含有一些web应用全局性方法,实现web资源共享、servlet转发等。通过
ServletConfig.getServletContext
方法获得,在<context-param>
标签配置。
ServletContext
概念
一个web应用所有servlet共享同一个ServletContext对象,可实现数据共享。ServletContext被称为context域对象。
域:作用范围;context域:整个应用程序范围。
ServletContext域:
- 这是一个容器
- 说明了这个容器的作用范围,也就是应用程序范围
转发:客户机一次请求;重定向:客户机两次请求
作用
- 获取web应用的初始化参数
- 实现servlet转发
- 利用ServletContext对象读取资源文件
- 获得文件路径
- 读取资源文件的三种方式
- .properties文件(属性文件)
配置文件:properties文件和xml文件;数据有关系使用xml文件,没有关系则使用properties文件。
1.通过ServletContext
的getResourceAsStream
方法,读取properties文件
模板代码(注意文件位置不同写路径会不同):
1 | InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/org/iot/servlet/db.properties"); |
2.通过servletContext
的getRealPath
方法得到资源的绝对路径,再通过传统方式(FileInputStream
)读取
3.通过类装载器去读,ClassLoader
的getResourceAsStream
(如果读取资源文件的程序不是servlet),文件不能太大。只装载一次,所以如要读到更新后的数据,通过类装载的方式得到资源文件的位置,再通过传统方式读取资源文件的数据(用getResource
得到path,再用FileInputStream
)