2.6.6 request对象 1. 获取请求头 获取请求参数

2.6.6 request对象

request对象是JSP中重要的对象,每个request对象封装着一次用户请求,并且所有的请求参数都被封装在request对象中,因此request对象是获取请求参数的重要途径。
除此之外,request可代表本次请求范围,所以还可用于操作request范围的属性。

1. 获取请求头 获取请求参数

web应用是请求/响应架构的应用,浏览器发送请求时通常总会附带一些请求头,还可能包含一些请求参数发送给服务器,服务器端负责解析请求头凊请求参数的就是JSPServlet,而JSPServlet取得请求参数的途径就是request.

获取请求参数方法

requestHttpServletrequest接口的实例,它提供了如下几个方法来获取请求参数。

获取请求参数方法 描述
String getParameter(String paramName) 获取paramName请求参数的值。
Map getParameterMap() 获取所有请求参数名和参数值所组成的Map对象
Enumeration getParameterNames() 获取所有请求参数名所组成的Enumeration对象。
String[] getParameterValues(String name) paramName请求参数的值,当该请求参数有多个值时,该方法将返回多个值所组成的数组。

获取请求头方法

HttpServletRequest提供了如下方法来访问请求头。

  • String getHeader(String name):根据指定请求头的值。
  • java.util.Enumeration<String> GetHeaderNames():获取所有请求头的名称。
  • java.util.Enumeration<String> getHeaders(String name):获取指定请求头的多个值
  • int getIntHeader(String name):获取指定请求头的值,并将该值转为整数值。

请求头和请求参数的区别

对于开发人员来说,请求头和请求参数都是由用户发送到服务器的数据,区别在于:
请求头通常由浏览器自动添加,因此一次请求总是包含若干请求头;
请求参数则通常需要开发人员控制添加,让客户端发送。

GET请求POST请求

客户端发送的请求参数通常分两种情况。

GET方式的请求

直接在浏览器地址栏输入访问地址所发送的请求或提交表单发送请求时,该表单对应的form元素没有设置method属性,或设置method属性为get,这几种请求都是GET方式的请求。GET方式的请求会将请求参数的名和值转换成字符串,并附加在原URL之后,因此可以在地址栏中看到请求参数名和值。且GET请求传送的数据量较小,一般不能大于2KB

POST方式的请求

这种方式通常使用提交表单(由form元素表示)的方式来发送,且需要设置form元素的method属性为postPOST方式传送的数据量较大,通常认为POST请求参数的大小不受限制,但往往取决于服务器的限制,POST请求传输的数据量总比GET传输的数据量大。而且POST方式发送的请求参数以及对应的值放在HTML HEADER中传输,用户不能在地址栏里看到请求参数值,安全性相对较高。

对比上面两种请求方式,不难发现,通常应该采用POST方式发送请求。

几乎每个网站都会大量使用表单,表单用于收集用户信息,一旦用户提交请求,表单的信息将会提交给对应的处理程序,如果为form元素设置method属性为post,则表示发送POST请求。

form.jsp

下面是表单页面的代码

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
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!DOCtype html>
<html>
<head>
<title> 收集参数的表单页 </title>
</head>
<body>
<form id="form1" action="request1.jsp">
用户名:<br/>
<input type="text" name="name"><hr/>
性别:<br/>
男:<input type="radio" name="gender" value="男">
女:<input type="radio" name="gender" value="女"><hr/>
喜欢的颜色:<br/>
红:<input type="checkbox" name="color" value="红">
绿:<input type="checkbox" name="color" value="绿">
蓝:<input type="checkbox" name="color" value="蓝"><hr/>
来自的国家:<br/>
<select name="country">
<option value="中国">中国</option>
<option value="美国">美国</option>
<option value="俄罗斯">俄罗斯</option>
</select><hr/>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>

这个页面没有动态的JSP部分,它只是包含一个收集请求参数的表单,且粗体字部分设置了该表单的actionrequestl.jsp,这表明提交该表单时,请求将发送到requestl.Jsp页面;粗体字代码还设置了methodpost,这表明提交表单将发送POST请求。
除此之外,表单里还包含1个文本框、2个单选框、3个复选框及1个下拉列表框,另外包括“提交”和“重置”两个按钮。页面的执行效果如图2.24所示。
在该页面中输入相应信息后,单击“提交”按钮,表单域所代表的请求参数将通过request对象的getParameter()方法来取得。

只有带有name属性的表单域才会生成请求参数

并不是每个表单域都会生成请求参数,而是有name属性的表单域才生成请求参数.关于表单堿和请求参数的关系遵循如下4点。

  • 每个有name属性的表单域对应一个请求参数。
  • 如果有多个表单域有相同的name属性,则多个表单域只生成一个请求参数,只是该参数有多个值。
  • 表单域的name属性指定请求参数名,value指定请求参数值。
  • 如果某个表单城设置了disabled=” ‘disabled“属性,则该表单域不再生成请求参数。

request1.jsp

上面的表单页向request1.jsp页面发送请求,request1.jsp页面的代码如下。

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
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<title> 获取请求头/请求参数 </title>
</head>
<body>
<%
// 获取所有请求头的名称
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements())
{
String headerName = headerNames.nextElement();
// 获取每个请求、及其对应的值
out.println(
headerName + "-->" + request.getHeader(headerName) + "<br/>");
}
out.println("<hr/>");

// 设置解码方式,对于简体中文,使用UTF-8解码
request.setCharacterEncoding("UTF-8"); // ①
// 下面依次获取表单域的值
String name = request.getParameter("name");
String gender = request.getParameter("gender");
// 如果某个请求参数有多个值,将使用该方法获取多个值
String[] color = request.getParameterValues("color");
String national = request.getParameter("country");
%>

<!-- 下面依次输出表单域的值 -->
您的名字:<%=name%><hr/>
您的性别:<%=gender%><hr/>
<!-- 输出复选框获取的数组值 -->
您喜欢的颜色:<%for(String c : color)
{out.println(c + " ");}%><hr/>
您来自的国家:<%=national%><hr/>
</body>
</html>

上述页面中的代码示范了如何获取请求头、请求参数.

请求参数的字符集

在获取表单域对应的请求参数值之前,先设置request编码的字符集(如①号代码所示).如果POST请求的请求参数里包含非西欧字符,则必须在获取请求参数之前先调用setCharacterEncoding()方法设置编码的字符集。

请求的字符集合表单页面的字符集一样

如果发送请求的表单页采用UTF-8字符集,该表单页发送的请求也将采用UTF-8字符集,所以本页面需要先执行如下方法:

  • request.setCharacterEncoding("UTF-8");:设置request编码所用的字符集。

测试

在表单提交页的各个输入域内输入对应的值,然后单击“提交”按钮,request1.jsp就会出现如图2.25所示的效果

如果需要传递的参数是普通字符串,而且仅需传递少量参数,可以选择使用GET方式发送请求参数,GET方式发送的请求参数被附加到地址栏的URL之后,地址栏的URL将变成如下形式:

1
url?param1=value1&param2=value2&......&paramN=valueN

URL和参数之间以“?”分隔,而多个参数之间以“&”分隔

request2.jsp

下面的JSP页面示范了如何通过request来获取GET请求参数值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!DOCTYPE html>
<html>
<head>
<title> 获取GET请求参数 </title>
</head>
<body>
<%
// 获取name请求参数的值
String name = request.getParameter("name");
// 获取gender请求参数的值
String gender = request.getParameter("gender");
%>
<!-- 输出name变量值 -->
您的名字:<%=name%><hr/>
<!-- 输出gender变量值 -->
您的性别:<%=gender%><hr/>
</body>
</html>

上面的页面中粗体字代码用于获取GET方式的请求参数,从这些代码不难看出:request获取POST请求参数的代码和获取GET请求参数代码完全一样
向该页面发送请求时直接在地址栏里增加一些GET方式的请求参数:

1
http://localhost:8080/jspObject/request2.jsp?name=川普&gender=女

执行效果如图2.26所示。

获取GET的请求参数值

细心的读者可能发现上面两个请求参数值都由英文字符组成,如果请求参数值里包含非西欧字符,那么是不是应该先调用setCharacterEncoding()来设置request编码的字符集呢?读者可以试一下。答案是不行,如果GET方式的请求值里包含了非西欧字符,则获取这些参数比较复杂.
下面的页面示范了如何获取GET请求里的中文字符。

request3.jsp

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
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!DOCTYPE html>
<html>
<head>
<title> 获取包含非西欧字符的GET请求参数 </title>
</head>
<body>
<%
// 获取请求里包含的查询字符串
String rawQueryStr = request.getQueryString();
out.println("原始查询字符串为:" + rawQueryStr + "<hr/>");
// 使用URLDecoder解码字符串
String queryStr = java.net.URLDecoder.decode(
rawQueryStr , "UTF-8");
out.println("解码后的查询字符串为:" + queryStr + "<hr/>");
// 以&符号分解查询字符串
String[] paramPairs = queryStr.split("&");
for(String paramPair : paramPairs)
{
out.println("每个请求参数名、值对为:" + paramPair + "<br/>");
// 以=来分解请求参数名和值
String[] nameValue = paramPair.split("=");
out.println(nameValue[0] + "参数的值是:" +
nameValue[1]+ "<hr/>");
}
%>
</body>
</html>

上面的程序中粗体字代码就是获取GET请求里中文参数值的关键代码,为了获取GET请求里的中文参数值,必须借助于java.net.URLDecoder类。关于URLDecoderURLEncoder两个类的用法请参考疯狂Java体系的《疯狂Java讲义》的17.2节。
上面页面代码使用了UIF-8字符集进行解码,到底应该用哪种字符集来解码,这取决于浏览器。对于简体中文的环境来说,一般要么是UTF8字符集,要么是GBK字符集。
读者可以编写一个表单,并让表单以GET方式提交请求到request3jsp页面,将可看到如图2.27所示的效果
如果读者不想这样做,还可以在获取请求参数值之后对请求参数值重新编码。也就是先将其转换成字节数组,再将字节数组重新解码成字符串。例如,可通过如下代码来取得name请求参数的参数值。

1
2
3
4
5
6
//获取原始的请求参数值
String rawName = request.getParameter("name");
//将请求参数值使用Iso-8859-1字符串分解成字节数组
byte [] rawBytes = rawName.getBytes("ISO-8859-1");
//将字节数组重新解码成字符串
String name = new String(rawBytes,"UTF-8");

通过上面代码片段也可处理GET请求里的中文请求参数值。