1. HttpServletRequest
1.1. HttpServletRequest简介
在Servlet Api中,定义了一个HttpServletRequest接口,它继承自ServletRequest,专门用于封装Http的请求。由于Http请求包含请求行、请求头和请求体三部分,因此在HttpServletRequest中分别定义了接受请求头、请求行和请求体的相关方法。
1.2. 请求行
1.2.1. 获取请求行相关信息的相关方法
(1)getMethod():返回请求方法,请求方法可能是GET或者POST,也有可能是HEAD、PUT或者DELETE。
(2)getRequestURI():返回URI(URI是URL从主机和端口之后到表单数据之前的那一部分)。如http://localhost:8080/my/test1?name=备份大V\&passWord=2342的URI为"/my/test1"。
(3)getRemoteAddr():用于获取客户端的IP地址。如:0:0:0:0:0:0:0:1
(4)getLocalAddr():用于获取服务器当前接受请求的IP地址。如:0:0:0:0:0:0:0:1
(5)getRemotePort():用于获取客户端的端口号。如:8080
(6)getContextPath():用于获取RUL中的属于web应用程序的路径。
(7)getProtocol():用于获取请行中的协议名和版本。如:HTTP/1.1
javascript
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("MyServlet收到GET请求");
System.out.println("请求方式:" + request.getMethod());
System.out.println("URI:" + request.getRequestURI());
System.out.println("发出请求客户端IP地址:" + request.getRemoteAddr());
System.out.println("服务点接收请求的IP地址:" + request.getLocalAddr());
System.out.println("访问客户端的端口号:" + request.getRemotePort());
System.out.println("web应用路径:" + request.getContextPath());
System.out.println("http协议和版本:" + request.getProtocol());
}
1.3. 请求头
获取请求头的相关方法
(1)getHeader (String name):用于获取一个指定头字段的值,如果请求头不包含此字段则返回null,如果包含多个该字段的值则返回第一个值。
(2)getIntHeader ():用于获取指定头字段的值,并且将其转化为int类型,如果不存在该字段则返回-1,如果获取的值不能转化成int类型则会发生NumberFormatException异常。
(3)getDataHeaderNames():用于获取指定头字段的值,并且将按照GMT时间格式转化成一个代表日期/时间的长整数。
(4)getHeaderNames():用于获取所有包含请求头字段的Enumerating。
javascript
//获取请求头
//accept:text/html, application/xhtml+xml, image/jxr, */*
//accept-language:zh-Hans-CN,zh-Hans;q=0.5
//user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
//accept-encoding:gzip, deflate
//host:localhost:8080
//connection:Keep-Alive
//cookie:JSESSIONID=73B0F51907B51DCCEc8b-855f-ad93239cf1f0
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String element = headerNames.nextElement();
System.out.println(element + ":" + request.getHeader(element));
}
1.4. 请求体
获取请求参数:
(1)getParameter(String name):用于获取某个指定名称的参数值,如果请求中没有包含指定名称的参数值,则返回空串"",如果包含多个该参数的值则返回第一个出现的参数值。
(2)getParameterNames():用于返回一个包含请求消息中的所有参数名的Enumerating。
(3) getParameterMap():用于将请求中的所有参数和值装入一个map对象然后返回。
1.5. 发送响应行
sendError(int sc, String msg):使用指定的状态码发送一个错误响应至客户端。服务器默认会创建一个HTML格式的服务错误页面作为响应结果,其中包含参数msg指定的文本信息,这个HTML页面的内容类型为"text/html",保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面将会优先于建议的msg参数服务于客户端。(ps:相比较上面的方法,我更倾向于前者。使用上面的方法,可以通过定制不同状态的响应结果显示于客户端,我们应该不想让客户端看到服务器创建出的简单粗暴的页面吧?)
setStatus(int sc):设置响应的状态码。这个方法被用于当响应结果正常时(例如,状态码为SC_OK或SC_MOVED_TEMPORARTLY)设置响应状态码。如果发生错误,而且来访者希望调用在web应用中定义的错误页面作为显示,那么应该使用sendError方法代替之。使用setStatus方法之后,容器会清空缓冲并设置Location响应头,保留cookies和其他响应头信息。
1.6. Servlet 生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
• Servlet 初始化后调用 init () 方法。
• Servlet 调用 service() 方法来处理客户端的请求。
• Servlet 销毁前调用 destroy() 方法。
• 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
现在让我们详细讨论生命周期的方法。
1.6.1. init() 方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
init 方法的定义如下:
javascript
public void init() throws ServletException {
// 初始化代码...
}
1.6.2. service() 方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
下面是该方法的特征:
javascript
public void service(ServletRequest request,
ServletResponse response)
throws ServletException, IOException{
}
service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。
doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。
1.6.3. doGet() 方法
GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
javascript
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
1.6.4. doPost() 方法
POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。
javascript
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
1.6.5. destroy() 方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:
javascript
public void destroy() {
// 终止化代码...
}
1.6.6. 架构图
下图显示了一个典型的 Servlet 生命周期方案。
• 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
• Servlet 容器在调用 service() 方法之前加载 Servlet。
• 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。