1.1 Servlet
1.1.1 Servlet简介
Servlet是运行在Web服务器中的Java小程序。Servlet 3.0规范定义了ServletAPI的实现以及部署Servlet的方法。BES应用服务器完全支持Servlet 3.0规范。
Servlet是BES应用服务器中运行的Java类,使用BES应用服务器中运行的Servlet可以执行以下操作:
1. 创建动态网页,动态网页可以使用HTML表单获取终端用户的输入,并为此输入提供响应。
2. 创建协作系统,例如在线会议。
3. 访问各种API和功能,例如:
1) 会话跟踪——允许网站跨多个网页跟踪用户的进展情况。此功能支持诸如使用购物车的电子商务网站之类的网站。BES应用服务器通过在服务器关闭之前和在集群服务器间共享的会话之间提供故障转移,可以支持数据库的会话持久性。
2) JDBC驱动程序——JDBC驱动程序提供了基本的数据库访问。通过BES应用服务器的多层JDBC实现,可以利用连接缓存池、服务器端数据缓存和事务。JDBC的使用请参看JDBC。
3) EJB——Servlet可使用EJB封装会话、数据库中的数据及其它功能。EJB的使用请参看EJB应用。
4) JMS——通过JMS,Servlet可以与其它Servlet和Java程序交换消息。JMS的使用请参看JMS。
5) Java JDK API——Servlet可使用标准的Java JDK API。
6) 转发请求——Servlet可将请求转发到其它Servlet或资源。
4. 任何符合Servlet规范的Servlet都可轻松地部署到BES应用服务器。
HTTP Servlet是特殊类型的Servlet,它通常以HTML页的形式处理HTTP请求并提供HTTP响应。BES HTTP Servlet还可以访问数据库、EJB、JMS、HTTP会话和BES应用服务器的其它工具。
1.1.2 编写Servlet
Servlet API提供了javax.servlet.Servlet接口,所有的Servlet必须实现该接口。ServletAPI还给出了HTTP协议的Servlet实现——javax.servlet.http.HTTPServlet,可以通过继承HTTPServlet类来编写自己的Servlet,HTTPServlet可以读取HTTP头、编写HTML编码来将响应传递到浏览器客户端。
Servlet 3.0规范可以使用注解@WebServlet来定义Servlet,使用注解@WebServlet标注的类必须继承javax.servlet.http.HTTPServlet类。下面的代码片段定义了一个映射到URL模式为/SendMailServlet的Servlet:
importjavax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@WebServlet("/SendMailServlet")
public class SendMailServlet extendsHttpServlet {
使用注解@WebServlet可以省掉在web.xml(web-fragment.xml)中配置Servlet。如果一个Servlet的实现类被标注了注解@WebServlet,同时也在web.xml(web-fragment.xml)中配置了该Servlet,则web.xml(web-fragment.xml)中的配置优先。注解@WebServlet的常用配置属性如下:
表1‑1 注解@WebServlet的常用配置
属性 |
用途 |
默认值 |
name |
指定Servlet的名称 |
“” |
value |
指定请求Servlet的URL模式,等同于urlPatterns |
{} |
urlPatterns |
指定请求Servlet的URL模式 |
{} |
loadOnStartup |
指定Servlet是否在WEB容器启动时初始化 |
-1 |
initParams |
指定Servlet的初始化参数 |
{} |
asyncSupported |
指定Servlet是否支持异步模式 |
False |
例:
@WebServlet(name="SendMailServlet",
urlPatterns="/SendMailServlet",
loadOnStartup=3,
initParams ={
@WebInitParam(name="greeting",value="welcome"),
@WebInitParam(name="name",value="developer")},
asyncSupported=true)
2.1.2.1 初始化Servlet
通常,BES应用服务器在对Servlet发出第一个请求时初始化Servlet,初始化Servlet时,BES应用服务器会执行该Servlet的init()方法。在WEB应用中定义的参数会在初始化期间传递给Servlet,例如,在实现Servlet的类上的注解@WebServlet中定义两个初始化参数:greeting(值为welcome)和name(值为developer):
@WebServlet(… …,
initParams={
@WebInitParam(name="greeting",value="welcome"),
@WebInitParam(name="name",value="developer")})
也可以将上面的初始化参数定义到WEB应用标准部署描述符web.xml(web-fragment.xml)中:
<servlet>
......
<init-param>
<param-name>greeting</param-name>
<param-value>welcome</param-value>
</init-param>
<init-param>
<param-name>name</param-name>
<param-value>developer</param-value>
</init-param>
</servlet>
Servlet的init()方法会执行BES应用服务器加载Servlet时所需执行的一切初始化工作。默认init()方法会执行BES应用服务器要求执行的所有初始化工作,可以通过重写Servlet的init()方法来实现所需的初始化功能,比如初始化计数器、创建数据库连接等。如果需要替换init(),请首先调用 super.init(),以便首先执行默认初始化操作。
2.1.2.2 处理请求、返回响应
Servlet的主要功能是从WEB浏览器中接受HTTP请求,并返回HTTP响应。此项工作由Servlet的service()方法完成。service()方法包括用于接收来自客户端数据的请求对象HttpServletRequest和用于创建输出的响应对象HttpServletResponse。
来自WEB浏览器的HTTP请求除了包含URL之外,还可以包含表单数据、客户端信息、Cookies、会话和查询参数的相关信息,HTTPServlet可通过HttpServletRequest对象获得请求中的这些信息。
使用向客户端提供响应的HttpServletResponse对象,可以设置能转换为HTTP头信息的几个Servlet特性,例如设置内容类型、字符编码、是否缓存等;也可以获得输出流,然后将响应内容以HTML格式写入输出流。
2.1.2.3 请求调度
Servlet可以将请求传递给另一个资源,如Servlet、JSP或HTML页,此过程称为请求调度。调度请求时,请使用RequestDispatcher接口的include()或forward()方法。通过使用RequestDispatcher,可以避免将HTTP重定向响应发送回客户端。RequestDispatcher会将HTTP请求传递到请求的资源。
要将请求调度到特定资源,请执行下列操作:
1. 获取对ServletContext的引用:
ServletContext sc = getServletConfig().getServletContext();
2. 使用下列方法之一查找RequestDispatcher对象:
RequestDispatcher rd = sc.getRequestDispatcher(String path);
该方法中,path是相对于WEB应用的根目录。
RequestDispatcher rd = sc.getNamedDispatcher(String name);
该方法中的name是WEB应用标准部署描述符web.xml中使用<servlet-name>元素为Servlet指定的名称。
RequestDispatcher rd = ServletRequest.getRequestDispatcher(String path);
此方法类似于ServletContext.getRequestDispatcher(String path)方法,只是它允许相对于当前Servlet的path。如果路径以/字符开头,则会将其解释为相对于WEB应用。通过在getRequestDispatcher()方法中请求资源的相应URL,可以为WEB应用中的任何HTTP资源(包括HTTP Servlet、JSP页或纯HTML页)获取RequestDispatcher。使用返回的RequestDispatcher对象将请求转发到另一个Servlet。
3. 使用适当的方法转发或包含请求。转发、包含请求的用法分别为:
1) rd.forward(request,response);
2) rd.include(request,response);
1.1.3 配置Servlet
编写好Servlet后,可以直接在类上标注注解@WebServlet来配置Servlet的名称和访问该Servlet的URL模式。注解@WebServlet的name属性定义Servlet的名称,urlPatterns属性定义调用该Servlet的URL模式,initParams属性定义Servlet的初始化参数:
@WebServlet(name="SendMailServlet",
urlPatterns="/SendMailServlet",
initParams={
@WebInitParam(name="greeting",value="welcome"),
@WebInitParam(name="name",value="developer")})
也可以在web.xml(web-fragment.xml)中为该Servlet配置访问URL。<servlet>元素定义servlet的名称、指定执行servlet的已编译类,并使用init-param元素定义servlet的初始化特性。<servlet-mapping>元素定义调用此servlet的URL模式。举例来说:
<!-- Servlet声明,为Servlet类取一个应用范围内唯一的名称 -->
<servlet>
<servlet-name>MailServlet</servlet-name>
<servlet-class>
samples.javamail.servlet.SendMailServlet
</servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Welcome</param-value>
</init-param>
</servlet>
<!-- 为声明的Servlet类配置URL,所有/mail请求都会交由MailServlet进行处理 -->
<servlet-mapping>
<servlet-name>MailServlet</servlet-name>
<url-pattern>/mail</url-pattern>
</servlet-mapping>
1.1.4 访问Servlet
访问或引用WEB应用中的Servlet时,URL按如下所示进行构造:
http://server:port/context-root/requestPath?requestParameters
表1‑2 访问WEB应用的URL构造元素说明
元素 |
说明 |
server:port |
为应用提供服务的主机名称及监听端口号。 |
context-root |
应用的访问根路径。 |
requestPath |
web.xml中为Servlet配置的URL格式。 |
requestParameters |
可选的HTTP请求参数名值对。 |