# 请求 ServletRequest
# 处理参数 Parameter
请求来到服务器时,Web 容器会创建 HttpServletRequest 实例来包装请求中的相关信息,HttpservletRequest
定义了取得请求信息的方法。例如,可以使用以下方法来取得请求参数:
getParameter(name: String) -> String
指定请求参数名称来取得相应的值 (String),因此可能需要解析为基本类型 (如 Integer)getParameterValues(name: String) -> String[]
针对可复选的组件,如复选框 CheckBox, 列表 List 等会出现一个参数名多个参数值的情况,返回一个 String 数组getParameterNames() -> Enumeration<String>
获取全部请求参数的名称,返回一个枚举对象。枚举对象的使用
1
2
3
4
5
Enumeration<String> e =req.getParameterNames();
while(e.hasMoreElements()) {
String param = e.nextElement();
}getParameterMap() -> Map<String, String[]>
将请求参数以 Map 对象键值对返回ParameterMap 的使用
1
2
3
4
5
6
Map<String, String[]> map = req.getParameterMap();
for(Map.Entry<String, String[]> entry: map.entrySet()) {
System.out.println(entry.getKey());
System.out.println(Arrays.toString(entry.getValue()));
}
示例代码
下面的 InputServlet 实现了一个简单的表单,它使用 POST 方法传递参数,并在 STDOUT 输出。
1 |
|
# 处理报头 Header
HTTP 中包含了请求标头 (Header) 信息,HttpServletRequest 上设计了一些方法可以用来取得标头信息。
getHeader(name: String) -> String
获取指定报头的值。如果不存在则返回 null。getHeaders(name:String) -> Enumeration<String>
某些报头可能出现多值(如 Accept-Language),此方法返回所有值的枚举。getHeaderNames() -> Enumeration<String>
获取请求中所有报头名称的枚举。getIntHeader(name: String) -> int
将报头值直接转换为整数。如果报头不存在返回 -1,如果转换失败则抛出 NumberFormatException。getDateHeader(name: String) -> long
将日期类型的报头(如 If-Modified-Since)转换为毫秒数。
示例代码
1 |
|
# 处理编码 CharacterEncoding
请求编码 (Request)
req.setCharacterEncoding(encoding: String)用于设置 POST 请求体(Body)的编码格式。注意: 必须在调用任何 getParameter () 方法之前调用此方法,否则配置将失效
对于 GET 请求,参数位于 URL 中,现代 Web 容器(如 Tomcat 8+)通常默认使用 UTF-8 解析,不需要手动设置。
响应编码 (Response)
为了确保浏览器正常显示,还需设置响应的编码:resp.setCharacterEncoding("UTF-8"): 设置响应实体的编码。
或resp.setContentType("text/html;charset=UTF-8"): 同时设置 MIME 类型和浏览器解析时使用的编码。
示例代码
1 |
|
# 响应 ServletResponse
# 响应报头 Header
一般情况下,浏览器自动设置这些报头的信息,当然我们也可以使用 HttpServletResponse 对象来设置响应标头。
setHeader(name: String, value: String)
设置指定标头的值。如果该标头已存在,新值将覆盖旧值。addHeader(name: String, value: String)
向现有标头添加值,允许一个标头对应多个值。setIntHeader(name: String, value: int)
设置整数值的标头。addIntHeader(name: String, value: int)
向现有标头添加整数值。setDateHeader(name: String, date: long)
设置日期值的标头(单位为毫秒)。addDateHeader(name: String, date: long)
向现有标头添加日期值。
示例代码
下面的代码演示了如何设置定时刷新以及如何禁止浏览器缓存。
1 |
|
# 状态代码 Status
有些标头必须搭配 HTTP 状态代码 (Status code),可以通过 HttpServletResponse 的 setStatus(sc: int) 方法来设置。
常用的状态码常量(定义在 HttpServletResponse 中):
SC_OK(200): 表示请求成功。SC_MOVED_TEMPORARILY(302): 临时重定向。SC_NOT_FOUND(404): 未找到资源。SC_INTERNAL_SERVER_ERROR(500): 服务器内部错误。
# 缓冲区 Buffer
容器可以(但非必要)对响应进行缓冲,通常容器默认都会对响应进行缓冲。
getBufferSize() -> int: 取得实际使用的缓冲区大小。setBufferSize(size: int): 设置首选缓冲区大小(需在响应提交前设置)。isCommitted() -> boolean: 检查响应是否已发送(提交)给客户端。reset(): 重置缓冲区、状态码以及响应头。resetBuffer(): 仅重置缓冲区内容,保留状态码与响应头。flushBuffer(): 强制将缓冲区的内容输出到客户端。
# 简单字符输出 PrintWriter
如果要对浏览器输出 HTML,通常通过 HttpServletResponse 的 getWriter() 方法取得 PrintWriter 对象。
1 |
|
需要注意的是,在没有设置任何内容类型或编码之前,HttpServletResponse 使用的字符编码默认是 ISO-8859-1。也就是说,如果直接输出中文,在浏览器上就会看到乱码。
# sendRedirect 和 sendError
sendRedirect(location: String)
发送 302 响应进行重定向。浏览器会自动访问新指定的 URL。sendError(sc: int)/sendError(sc: int, msg: String)
发送错误代码(如 404, 403)。容器通常会截获该错误并展示预定义的错误页面。
示例代码
1 |
|
# 请求分发 RequestDispatcher 和 请求重定向 Redirect
我们先定义两个简单的 Servlet 业务,在第一个 Servlet 中通过请求转发和重定向,显示第二个 Servlet 的内容。
1 |
|
1 |
|
# 请求分发 RequestDispatcher
在 Web 应用程序中,经常需要多个 Servlet 来完成请求。
例如,将另一个 Servlet 的请求处理流程包含 (Include) 进来,或将请求转发 (Forward) 给别的 Servlet 处理。
在请求转发中:
- 请求 / 响应次数:一共有 1 次请求,1 次响应
- URL 地址栏:不变(请求的第一个服务器资源的 URL)
- 发生位置:服务器内部
- 是否共享请求参数:是
包含 Include
以开头的 Servlet-1 为例,在 TODO 区域填充:1
2
3
RequestDispatcher rd = req.getRequestDispatcher("/servlet-2");
rd.include(req, resp)
当用户访问/servlet-1时的效果:1
2
3
4
// 请求完成后的URL: /servlet-1
Hello from Fug Servlet 1, and I will go to Servlet 2!
Hello from Fug Servlet 2!转发 Forward
以开头的 Servlet-1 为例,在 TODO 区域填充:1
2
3
RequestDispatcher rd = req.getRequestDispatcher("/servlet-2");
rd.forward(req, resp)
当用户访问/servlet-1时的效果:1
2
3// 请求完成后的URL: /servlet-1
// Servlet-1 的内容将不会显示
Hello from Fug Servlet 2!
# 请求重定向 Redirect
在请求重定向中:
- 请求 / 响应次数:有 N 次重定向,就要有 N 次请求,N 次响应
- URL 地址栏:请求的最后一个服务器资源的 URL
- 发生位置:客户端
- 是否共享请求参数:否
还是以开头的 Servlet-1 为例,在 TODO 区域填充:
1 |
|
当用户访问 /servlet-1 时的效果:
1 | // 请求完成后的URL: /servlet-2 |