《Servlet生命周期》一文提到,在 Servlet 生命周期的运行阶段,Servlet 容器会为当前的客户端请求创建一个 HttpServletRequest 对象和一个 HttpServletResponse 对象(这两个对象分别继承自 ServletRequest 和 ServletResponse),其中:
HttpServletRequest 对象代表客户端(浏览器)的请求,当客户端通过 HTTP 协议访问服务器时,HTTP 请求中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
以下是 HttpServletRequest 对象获取请求信息的一些方法以及代码示例:
获取客户端信息 | |
---|---|
getRequestURL() | 返回客户端发出请求时的完整 URL。 |
getRequestURI() | 返回请求行中的资源名部分。 |
getQueryString() | 返回请求中的参数部分。 |
getRemoteAddr() | 返回发出请求的客户机的 IP 地址 。 |
getRemoteHost() | 返回发出请求的客户机的完整主机名。 |
getRemotePort() | 返回客户机所使用的网络端口号。 |
getLocalAddr() | 返回 WEB 服务器的 IP 地址。 |
getLocalName() | 返回 WEB 服务器的主机名 。 |
getMethod() | 根据客户机的请求方式,返回生成这个请求的HTTP方法名称(GET、 POST等)。 |
获得客户端请求头 | |
getHeader(String name) | 以 String 的形式返回指定请求头的值。 |
getHeaders(String name) | 以 String 对象的 Enumeration 形式返回指定请求头的所有值。 |
getHeaderNames() | 返回此请求包含的所有头名称的枚举。 |
获得客户机请求参数(客户端提交的数据) | |
getParameter(String name) | 根据 name 获取请求参数的值。 |
getParameterMap() | 返回的是一个 Map 类型的值,该返回值记录着客户端所提交的请求参数和请求参数值的映射关系。 |
下面是一段简单的演示代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("getRequestURL: " + request.getRequestURL());
System.out.println("getRequestURI: " + request.getRequestURI());
System.out.println("getQueryString: " + request.getQueryString());
System.out.println("getRemoteHost: " + request.getRemoteHost());
System.out.println("getRemotePort: " + request.getRemotePort());
System.out.println("getLocalAddr: " + request.getLocalAddr());
System.out.println("getLocalName: " + request.getLocalName());
System.out.println("getLocalPort: " + request.getLocalPort());
System.out.println("getMethod: " + request.getMethod());
System.out.println("-------request.getParamterMap()-------");
// 得到请求的参数Map,注意map的value是String数组类型
Map map = request.getParameterMap();
Set<String> keySet = map.keySet();
for (String key : keySet) {
String[] values = (String[]) map.get(key);
for (String value : values) {
System.out.println(key + "=" + value);
}
}
System.out.println("--------request.getHeader()--------");
// 得到请求头的name集合
Enumeration<String> em = request.getHeaderNames();
while (em.hasMoreElements()) {
String name = (String) em.nextElement();
String value = request.getHeader(name);
System.out.println(name + "=" + value);
}
}
在浏览器地址栏中访问下面的 URL:
?后面跟的是参数,多个参数之间用&连接。
控制台输出结果:
与 HttpServletRequest 相反,HttpServletResponse 对象是专门用来封装 HTTP 响应消息的。客户端发出了请求,得对人家有所回应呀,HttpServletResponse 就是做这项工作的。
由于 HTTP 响应消息分为状态行、响应消息头、响应消息体三部分,因此,在 HttpServletResponse 接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。
① void setStatus(int status)该方法用于设置 Http 响应消息的状态码,并生成响应状态行。
由于响应状态行中的状态描述信息直接与状态码相关,而 HTTP 版本由服务器确定,因此,只要通过 setStatus() 方法设置了状态码,即可实现状态行的发送。
需要注意的是,在正常情况下,Web 服务器会默认产生一个状态码为 200 的状态行。
② void sendError(int sc)该方法用于发送表示错误信息的状态码。例如,404 状态码表示找不到客户端请求的资源。
HttpServletResponse 对象提供了两个重载的 sendError(int sc) 方法,具体如下:
在上面重载的两个方法中,第一个方法只发送错误信息的状态码,而第二个方法除了发送状态码以外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。
方法声明 | 功能描述 |
---|---|
void addHeader(String name,String value) | 这两个方法都是用来设置 HTTP 协议的响应头字段,其中:
|
void setHeader(String name,String value) | |
void addIntHeader(String name,int value) | 这两个方法专门用于设置包含整数值的响应头,避免了「使用 addHeader() 与 setHeader() 方法时需要将 int 类型的设置值转换为 string 类型」的问题。 |
void setIntHeader(String name,int value) | |
void setContentLength(int len) | 该方法用于设置响应消息的实体内容的大小,单位为字节。对于 HTTP 协议来说,这个方法就是设置 Content-Length 响应头字段的值。 |
void setContentType(String type) | 该方法用于设置 Servlet 输出内容的 MIME 类型。对于 HTTP 协议来说,就是设置 Content-Type 响应头字段的值。举例说明:
|
void setLocale(Locale loc) | 该方法用于设置响应消息的本地化消息。对 HTTP 来说,就是设置 Content-Language 响头字段和 Content-Type 头字段中的字符集编码部分。 需要注意的是,如果 HTTP 消息没有设置 Content-Type 头字段,setLocale() 方法设置的字符编码则没有效果,如果调用 setCharacterEncoding() 或 setContentType() 方法指定了响应头内容的字符集编码,则 setLocale() 方法将不再具有指定字符集编码的功能。 |
void setCharacterEncoding(String charset) | 该方法用于设置 out 输出流中所采用的编码。对 HTTP 协议来说,就是设置 Content-Type 头字段中的字符集编码部分。如果没有设置 Content-type 头字段,setCharacterEncoding() 方法设置的字符集编码则没有效果。 该方法的优先级比setContentType()和setLocale()方法要高,它的设置结果将覆盖setContentType()和setLocale()方法所设置的字符编码。 |
① ServletOutputStream getOutputStream()方法该方法所获取的字节输出流对象为 ServletOutputStream 类型。
由于 ServletOutputStream 是 OutputStream 的子类,它可以直接输出字节数组中的二进制数据,因此,要想输出二进制格式的响应正文,就需要使用 getOutputStream() 方法。
② PrintWriter getWriter()方法它返回了一个可以向客户端发送文本的的 Java.io.PrintWriter 对象。
由于 PrintWriter 类型的对象可以直接输出字符文本内容,因此,要想输出内容全为字符文本的网页文档,需要使用 getWriter() 方法。
默认情况下,PrintWriter 对象使用 ISO-8859-1 编码(该编码在输入中文时会发生乱码,乱码问题后面章节会讲到)。
注意:虽然HttpServletResponse 对象的 getOutSream() 和 getWriter() 方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。