1.12 小结

Servlet技术是Java EE技术的一部分。所有Servlet都 运行在Servlet容器中,容器和Servlet间的接口为 javax.servlet.Servletjavax.servlet包还提供了一个名为GenericServletServlet实现类,该类是一个辅助类,以便可以方便的创建一个servlet。不过,大部分servlet都 运行在HTTP环境中,因此派生一个 javax.servlet.http.HttpServlet的子类更为有用,注意 HttpServlet也是GenericServlet的子类。

1.11 使用部署描述符

如在前面的例子中所见,编写和部署Servlet都是很容易的事情。部署的一个方面是用一个路径配置Servlet 的映射。在这些范例中,是利用WebServlet注解来将一个URL路径映射了一个Servlet,如下所示:

1
2
3
4
@WebServlet(
name = "FormServlet",
urlPatterns ={"/form"}
)

利用部署描述符是配置Servlet应用程序的另一种方法,部署描述符的详情将在第13章“部署描述符”中探讨。部署描述符总是命名为web.xml,并且放在WEB-INF目录下

程序示例

本章介绍了如何创建一个名为app01cServlet应用程序,并为它编写了一个web.xml
创建app01c项目然后在src目录下创建app01c包,app01c包中有SimpleServletWelcomeServlet这样两个Servlet,还有一个要映射Servlets的部署描述符web.xml

SimpleServlet类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package app01c;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SimpleServlet extends HttpServlet
{
private static final long serialVersionUID = 8946L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer
.print("<html><head></head>"
+ "<body>Simple Servlet</body></html");
}
}

WelcomeServlet类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package app01c;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WelcomeServlet extends HttpServlet
{
private static final long serialVersionUID = 27126L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print(
"<html><head></head>" +
"<body>Welcome</body></html>");
}
}

部署描述文件web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>app01c</display-name>
<servlet>
<!-- 部署名 -->
<servlet-name>SimpleServlet</servlet-name>
<!-- 类全名 -->
<servlet-class>app01c.SimpleServlet</servlet-class>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<!-- 部署名 -->
<servlet-name>SimpleServlet</servlet-name>
<!-- URL -->
<url-pattern>/simple</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>app01c.WelcomeServlet</servlet-class>
<load-on-startup>20</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
</web-app>

使用部署描述符的好处

使用部署描述符有诸多好处。

  • 其一,可以使用在@WebServlet中没有的元素,如load-on-startup 元素。使用这个元素可以在应用程序启动时就调用init方法来实例化Servlet,而不是在用户第一次访问该Servlet是时调用init方法来实例化Servlet。如果init方法很耗时的话,这样可以减少用户第一次访问时的等待时间。
  • 使用部署描述符的另一个好处是,如果需要修改配置值,如Servlet路径,则不需要重新编译Servlet

运行效果

现在,在部署描述符中声明SimpleServletWelcomeServlet,可以利用这些URL来访问它们:
http://localhost:8080/app01c/simple
http://localhost:8080/app01c/welcome

浏览器显示效果如下:
这里有一张图片
这里有一张图片

关于部署以及部署描述符的更多信息,请参考第13章。

1.10 处理HTML表单

一个Web应用程序中几乎总会包含一个或者多个HTML表单,供用户输入值。你可以轻松地将一个HTML表单从一个Servlet发送到浏览器。
当用户提交表单时,在表单元素中输入的值就会被当作请求参数发送到服务器。HTML输入域(文本域、隐藏域或者密码域)或者文本区的值,会被当作字符串发送到服务器。空的输入域或者文本区会发送空的字符串。因此,**凡是有输入域名称的,ServletRequest.getParameter方法绝对不会返回null**。

select元素

HTMLselect元素也向header发送了一个字符串。如果select元素中没有任何选项被选中,那么就会发出所显示的这个选项值。包含多个值的select元素(允许选择多个选项并且 用<select-multiple>表示的select元素)发出一个字符串 数组,并且必须通过SelectRequest.getParameterValues方法进 行处理。

复选框

复选框比较奇特。核查过的复选框会发送字符串”on“到服务器。未经核查的复选框则不向服务器发送任何内容,此时ServletRequest.getParameter(fieldName)将返回null

单选框

单选框将被选中按钮的值发送到服务器。如果没有选择任何按钮,将没有任何内容被发送到服务器,此时ServletRequest.getParameter(fieldName)将返回null

多个同名元素的情况

如果一个表单中包含多个输入同名的元素,那么所 有值都会被提交,此时必须利用 ServletRequest.getParameterValues方法来获取它们。 如果你使用ServletRequest.getParameter方法的话将只返回最后一个值。

实例

下面的FormServlet类示范了如何处理HTML 表单。它的**doGet方法将一个Order表单发送到浏览器。 它的doPost方法获取到表单之中输入的值**,并将它们输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package app01a;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
name = "FormServlet",
urlPatterns =
{"/form"}
)
public class FormServlet extends HttpServlet
{
private static final long serialVersionUID = 54L;
private static final String TITLE = "Order Form";
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>" + TITLE + "</title></head>");
writer.println("<body><h1>" + TITLE + "</h1>");
writer.println("<form method='post'>");
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>Name:</td>");
writer.println("<td><input name='name'/></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Address:</td>");
writer.println("<td><textarea name='address' "
+ "cols='40' rows='5'></textarea></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Country:</td>");
writer.println("<td><select name='country'>");
writer.println("<option>United States</option>");
writer.println("<option>Canada</option>");
writer.println("</select></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Delivery Method:</td>");
writer.println("<td><input type='radio' " +
"name='deliveryMethod'"
+ " value='First Class'/>First Class");
writer.println("<input type='radio' " +
"name='deliveryMethod' "
+ "value='Second Class'/>Second Class</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Shipping Instructions:</td>");
writer.println("<td><textarea name='instruction' "
+ "cols='40' rows='5'></textarea></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>&nbsp;</td>");
writer.println("<td><textarea name='instruction' "
+ "cols='40' rows='5'></textarea></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Please send me the latest " +
"product catalog:</td>");
writer.println("<td><input type='checkbox' " +
"name='catalogRequest'/></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>&nbsp;</td>");
writer.println("<td><input type='reset'/>" +
"<input type='submit'/></td>");
writer.println("</tr>");
writer.println("</table>");
writer.println("</form>");
writer.println("</body>");
writer.println("</html>");
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>" + TITLE + "</title></head>");
writer.println("</head>");
writer.println("<body><h1>" + TITLE + "</h1>");
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>Name:</td>");
writer.println("<td>" + request.getParameter("name")
+ "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Address:</td>");
writer.println("<td>" + request.getParameter("address")
+ "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Country:</td>");
writer.println("<td>" + request.getParameter("country")
+ "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Shipping Instructions:</td>");
writer.println("<td>");
String[] instructions = request
.getParameterValues("instruction");
if(instructions != null) {
for(String instruction: instructions) {
writer.println(instruction + "<br/>");
}
}
writer.println("</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Delivery Method:</td>");
writer.println("<td>"
+ request.getParameter("deliveryMethod")
+ "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Catalog Request:</td>");
writer.println("<td>");
if(request.getParameter("catalogRequest") == null) {
writer.println("No");
} else {
writer.println("Yes");
}
writer.println("</td>");
writer.println("</tr>");
writer.println("</table>");
writer.println("<div style='border:1px solid #ddd;" +
"margin-top:40px;font-size:90%'>");
writer.println("Debug Info<br/>");
Enumeration<String> parameterNames = request
.getParameterNames();
while(parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
writer.println(paramName + ": ");
String[] paramValues = request
.getParameterValues(paramName);
for(String paramValue: paramValues) {
writer.println(paramValue + "<br/>");
}
}
writer.println("</div>");
writer.println("</body>");
writer.println("</html>");
}
}

利用下面的URL,可以调用FormServlet
http://localhost:8080/Hello/app01b/form
这样Servlet容器会调用的doGet方法,doGet()方法会如下的HTML表单发送给浏览器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<form method='post'>
<input name='name' />
<textarea name='address' cols='40' rows='5'></textarea>
<select name='country'>");
<option>United States</option>
<option>Canada</option>
</select>
<input type='radio' name='deliveryMethod' value='First Class' />
<input type='radio' name='deliveryMethod' value='Second Class' />
<textarea name='instruction' cols='40' rows='5'></textarea>
<textarea name='instruction' cols='40' rows='5'></textarea>
<input type='checkbox' name='catalogRequest' />
<input type='reset' />
<input type='submit' />
</form>

然后浏览器将解析这个HTML并显示,浏览器中的显示效果如下:
这里有一张图片
get请求响应得到的表单的方法设为post,确保当用户提交表单时,使用HTTP POST方法提交。**而它的action属性默认,这表示该表单会被提交给请求它时用的相同的URL**,还是http://localhost:8080/Hello/form这个URL.
现在,填写表单,并单击Submit按钮。如下图所示:
这里有一张图片
因为表单设置的方法为post,所以我们在表单中输入的值,将通过HTTP POST方法被发送给服务器,这 样就会调用ServletdoPost方法。doPost()方法给出响应.浏览器得到响应后显示如下:
这里有一张图片

总结

  • 表单中的action属性若为空,则表单数据将提交给到当前URL.
  • 当第一次输入URL是使用的是get请求,调用的是HttpServletdoGet方法.

1.9.3 HttpServletResponse接口

HttpServletResponse表示HTTP环境中的Servlet响应。下面是它里面定义的部分方法:

方法 描述
void addCookie(Cookie cookie) 给这个响应对象添加一个cookie
void addHeader(java.lang.String name, java.lang.String value) 给这个响应对象添加一个header
void sendRedirect(java.lang.String location) 发送一条响应码,将浏览器跳转到指定的位置,也就是请求重定向

1.9.2 HttpServletRequest接口

HttpServletRequest表示HTTP环境中的Servlet请求。它扩展javax.servlet.ServletRequest接口,并添加了几个方法。

HttpServletRequest接口新增方法

HttpServletRequest接口新增的部分方法如表所示:

方法 描述
java.lang.String getContextPath() 返回表示请求上下文的请求URI部分。
Cookie[] getCookies() 返回一个Cookie对象数组。
java.lang.String getHeader(java.lang.String name) 返回指定HTTP标题的值。
java.lang.String getMethod() 返回生成这个请求的HTTP方法名称。
java.lang.String getQueryString() 返回请求URL中的查询字符串。
HttpSession getSession() 返回与这个请求相关的会话对象。如果没有,将创 建一个新的会话对象。
HttpSession getSession(boolean create) 返回与这个请求相关的会话对象。如果有,并且 create参数为true,将创建一个新的会话对象。

1.9 Http Servlets

不说全部,至少大多数应用程序都要与HTTP结合 起来使用。这意味着可以利用HTTP提供的特性。 javax.servlet.http包是Servlet API中的第二个包,其中包 含了用于编写Servlet应用程序的类和接口。 javax.servlet.http中的许多类型都覆盖javax.servlet中的 类型。 下图展示了javax.servlet.http中的主要类型。
这里有一张图片

1.9.1 HttpServlet

HttpServlet类覆盖了javax.servlet.GenericServlet类。 使用HttpServlet时,还要借助分别代表Servlet请求和Servlet响应的HttpServletRequestHttpServletResponse对象。HttpServletRequest接口扩展 javax.servlet.ServletRequestHttpServletResponse扩展 javax.servlet.ServletResponseHttpServlet覆盖GenericServlet中的service方法,并通过下列签名再添加一个service方法:

1
2
3
protected void service(HttpServletRequest request, 
HttpServletResponse response)
throws ServletException, java.io.IOException

service方法和javax.servlet.Servletservice方法之间的区别在于方法的参数列表上,前者使用HttpServletRequestHttpServletResponse作为形式参数,而不是ServletRequestServletResponse。 像往常一样,Servlet容器调用javax.servlet.Servlet中原始的service方法。HttpServlet中的编写service方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void service(ServletRequest req,
ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(
"non-HTTP request or respons e");
}
service(request, response);
}

原始的service方法将Servlet容器创建的requestresponse对象分别转换成HttpServletRequestHttpServletResponse类对象,并调用新的service方法。这种转换总是会成功的,因为Servlet容器在调用Servlet的service方法时, Servlet容器总会传入一个HttpServletRequest和一个HttpServletResponse,预备使用HTTP。所以在通过实现 javax.servlet.Servlet,或者扩展(继承)javax.servlet.GenericServlet的创建的Servlet类中,也可以将传给service方法的servletRequestservletResponse分别转换成HttpServletRequestHttpServletResponse
然后,HttpServlet中的service方法会检验用来发送请求的HTTP方法(通过调用request.getMethod),并调 用以下方法之一:doGetdoPostdoHeaddoPutdoTracedoOptionsdoDelete。这7种方法中,每一种 方法都表示一个HTTP方法。doGet和doPost是最常用 的。因此,不再需要覆盖service方法了,只要覆盖 doGet或者doPost,或者覆盖doGet和doPost即可

总之,HttpServlet有两个特性是GenericServlet所不 具备的:

  • 不用覆盖service方法,而是覆盖doGet方法或者doPost方法, 或者同时覆盖doGetdoPost。在少数情况下,还会覆盖以下任意方法:doHeaddoPutdoTracedoOptionsdoDelete
  • 使用HttpServletRequestHttpServletResponse,而不 是ServletRequestServletResponse

1.7 ServletContext接口

  • ServletContext官方叫servlet上下文,每个应用(或者叫项目,工程,…)都会有一个ServletContext对象与之关联.工程内部的所有Servlet都共享这个ServletContext对象,因此可以叫做全局应用程序共享对象
  • 当容器分布在多个虚拟机上时,web应用在所分布的每个虚拟机上都拥有一个ServletContext实例与之关联。缺省情况下,ServletContext不是分布式的,并且只存在于一个虚拟机上。

ServletContext的作用

通过ServletContext可以访问应用范围的初始化参数和属性:

Servlet中如何获取ServletContext对象

通过在ServletConfig中调用getServletContext方法, 可以获得ServletContext

操作属性方法

保存在ServletContext中的对象被称作属性,ServletContext中的下列方法负责处理属性:

方法 描述
java.lang.Object getAttribute(java.lang.String name) 获取属性
java.util.Enumeration<java.lang.String> getAttributeNames() 获取属性枚举
void setAttribute(java.lang.String name, java.lang.Object object) 设置属性
void removeAttribute(java.lang.String name) 移除属性

参考资料

https://baike.baidu.com/item/servletContext/6758455
https://blog.csdn.net/qq_36371449/article/details/80314024

1.6 ServletConfig接口

接口方法

方法 描述
String getInitParameter(String name) 获取具有给定名称的初始化参数的值。
Enumeration<String> getInitParameterNames() Enumeration<String>对象的形式返回servlet的初始化参数的名称,如果servlet没有初始化参数,则返回空的Enumeration
ServletContext getServletContext() 返回与所在项目关联的ServletContext的引用。
String getServletName() 返回此servlet实例的名称。

接口描述

Servlet容器初始化Servlet时,Servlet容器会给 Servletinit方法传入一个ServletConfig对象。ServletConfig 封装可以通过@WebServlet或者通过部署描述符来传给Servlet 的配置信息。这样传入的每一条信息就叫一个初始参数。一个初始参数有keyvalue两个部分。 为了从Servlet内部获取到初始参数的值,要在 Servlet容器传给Servletinit方法的ServletConfig中调用 getInitParameter方法。getInitParameter的方法签名如 下:

1
java.lang.String getInitParameter(java.lang.String name)

此外,getInitParameterNames方法则是返回所有初 始参数名称的一个Enumeration

1
java.util.Enumeration<java.lang.String> getInitParameterNames()

例如,为了获取contactName参数值,要使用下面的方法签名:

1
2
String contactName = 
servletConfig.getInitParameter("contactName");

getInitParametergetInitParameterNames外,ServletConfig还提供了另一个很有用的方法: getServletContext。利用这个方法可以从Servlet内部获取ServletContext。关于这个对象的深入探讨,请查阅本 章1.7节。

实例

下面举一个ServletConfig的范例,在app01a项目中的src目录中的app01a包中添加 一个名为ServletConfigDemoServletServlet。这个新的 Servlet如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package app01a;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@WebServlet(
name = "ServletConfigDemoServlet",
urlPatterns =
{"/servletConfigDemo"},
// 设置Servlet的初始化参数
initParams =
{
@WebInitParam(
name = "admin",
value = "Harry Taciak"
),
@WebInitParam(
name = "email",
value = "admin@example.com"
)}
)
public class ServletConfigDemoServlet
implements
Servlet
{
private transient ServletConfig servletConfig;
@Override
public ServletConfig getServletConfig()
{
return servletConfig;
}
@Override
public void init(ServletConfig servletConfig)
throws ServletException
{
this.servletConfig = servletConfig;
}
@Override
public void service(ServletRequest request,
ServletResponse response)
throws ServletException,IOException
{
// 获取ServletConfig实例
ServletConfig servletConfig = getServletConfig();
// 获取Servlet的初始化参数
String admin = servletConfig.getInitParameter("admin");
String email = servletConfig.getInitParameter("email");
// 获取Servlet的名称
String servletName = servletConfig.getServletName();
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print("<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "Admin: " + admin + "<br/>"
+ "Email: " + email + "<br/>"
+ "ServletName: " + servletName + "<br/>"
+ "</body>"
+ "</html>");
}
@Override
public String getServletInfo()
{
return "ServletConfig demo";
}
// 实现接口方式必须实现该接口中的所有方法
@Override
public void destroy()
{}
}

@WebServletinitParams属性 中,给Servlet传入了两个初始参数(adminemail):

1
2
3
4
5
6
7
8
9
10
11
12
13
@WebServlet(
name = "ServletConfigDemoServlet",
urlPatterns ={"/servletConfigDemo"},
initParams ={
@WebInitParam(
name = "admin",
value = "Harry Taciak"
),
@WebInitParam(
name = "email",
value = "admin@example.com"
)}
)

运行效果

注意这里的urlPatterns是对于项目路径而言,/servletConfigDemoHello项目中的路径.加上项目路径,可以调用ServletConfigDemoServlet,如下所示:
http://localhost:8080/app01a/servletConfigDemo
浏览器将会显示以下文本:

1
2
3
Admin: Harry Taciak
Email: admin@example.com
ServletName: ServletConfigDemoServlet

部署描述符中设置Servlet的初始化参数

另一种方法是,在部署描述符中传入初始参数。使用部署描述符设置Servlet的初始参数,比使用@WebServlet更容易,因为部署描述符是一个文本文件,不需要重新编译Servlet,就可以对它进行编辑。部署描述符将在本章后续”使用部署描述符”小节以及第13章中详细讲解。

总结

  • ServletConfig操作的是Servlet的初始化参数。

1.5 ServletResponse接口

javax.servlet.ServletResponse接口表示一个Servlet响应。在调用Servletservice方法前,Servlet容器首先创建一个ServletResponse类对象,并将它作为第二个参数传给 service方法。ServletResponse隐藏了向浏览器发送响应的复杂过程。

getWriter方法

ServletResponse中有一个getWriter方法,它返回了一个可以向客户端发送文本的 java.io.PrintWriter类对象。默认情况下,PrintWriter对象使用的编码是 ISO-8859-1编码。
**在向客户端发送响应时,大多数时候是将响应作为 HTML发送的**。因此,你必须非常熟悉HTML`。

getOutputStream方法

还有一个方法可以用来向浏览器发送输出,它就是** getOutputStream方法。但这个方法是用于发送二进制数据**的,因此,大多数情况使用的是getWriter,而不是getOutputStream

setContentType方法

在发送任何HTML标签前,应该先调用setContentType方法,设置响应的内容类型,并将"text/html"作为一个参数传入。这是在告诉浏览器, 内容类型为HTML。在没有内容类型的情况下,大多数浏览器会默认将响应渲染成HTML。但是,如果没有设置响应内容类型,有些浏览器就会将HTML标签显示为普通文本。

1.4 ServletRequest接口

对于每一个HTTP请求,Servlet容器都会创建一个 ServletRequest实例,并将它作为参数传给Servletservice方法ServletRequest封装了关于这个请求的信息

ServletRequest接口方法

方法 描述
public int getContentLength() 返回请求主体的字节数。如果不知道字节长度,这个方法就会返回-1
public java.lang.String getContentType() 返回请求主体的MIME类型,如果不知道类型,返回null
public java.lang.String getProtocol() 返回这个HTTP请求的协议名称和版本。
public java.lang.String getParameter(java.lang.String name) 返回指定请求参数的值。

getParameter是在ServletRequest中最常用的方法。该方法通常用于返回HTML表单域的值。在本章后续 的“处理表单”小节中,将会学到如何获取表单值。 getParameter也可以用于获取查询字符串的值。例如,利用下面的URI调用Servlethttp://domain/context/servletName?id=123用下面这个语句,可以通过Servlet内部获取id值:

1
String id = request.getParameter("id"); 

注意,如果该参数不存在,getParameter方法将返回null。除了getParameter外,还可以使用 getParameterNamesgetParameterMapgetParameterValues获取表单域的名、值以及查询字符 串。这些方法的使用范例请参阅“Http Servlets”小节。