当浏览器访问Servlet时,Tomcat会创建一个HttpServletRequest对象,把这个对象作为参数传给service方法。这个对象里封装了浏览器发过来的所有请求信息,包括请求参数、请求头、请求方式、Cookie等等。
一、获取请求参数的方法
| 方法 | 返回值 | 作用 | 使用场景 |
|---|---|---|---|
getParameter(String name) |
String | 获取指定名称的参数值 | 最常见的用法,参数只有一个值的时候用 |
getParameterValues(String name) |
String[] | 获取同名参数的所有值 | 复选框、多选的爱好 |
getParameterNames() |
Enumeration<String> | 获取所有参数名的枚举 | 遍历所有参数,不知道具体有哪些参数时用 |
getParameterMap() |
Map<String, String[]> | 获取所有参数的Map集合 | 封装成JavaBean、打印所有参数调试 |
二、获取请求行信息的方法
| 方法 | 返回值 | 作用 | 使用场景 |
|---|---|---|---|
getRequestURL() |
StringBuffer | 获取完整的请求URL(从http开始到?前面结束) | 记录完整访问地址、生成绝对路径 |
getRequestURI() |
String | 获取请求的URI(站点名+Servlet路径) | 权限控制、判断访问的资源 |
getQueryString() |
String | 获取请求行中的参数部分(?后面的内容) | 记录原始参数、日志追踪 |
getMethod() |
String | 获取客户端的请求方式(GET/POST等) | 区分处理不同请求方式 |
getProtocol() |
String | 获取HTTP版本号(HTTP/1.1等) | 协议兼容性判断 |
getContextPath() |
String | 获取webapp名字(站点名,带斜杠) | 拼接路径、生成链接 |
后三个一般用得不多
三、完整代码示例
java
@WebServlet("/requestDemo")
public class RequestDemoServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse resp) {
// 假设请求地址:http://localhost:8080/demo/requestDemo?username=张三&hobby=篮球&hobby=足球
// ========== 获取请求参数 ==========
// 1. getParameter - 获取单个参数
String username = request.getParameter("username");
System.out.println("用户名:" + username);
// 2. getParameterValues - 获取多个值(比如爱好)
String[] hobbies = request.getParameterValues("hobby");
if (hobbies != null) {
System.out.println("爱好:" + Arrays.toString(hobbies));
}
// 3. getParameterNames - 遍历所有参数名
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = request.getParameter(name);
System.out.println("参数名:" + name + ",值:" + value);
}
// 4. getParameterMap - 获取所有参数的Map
Map<String, String[]> paramMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
String name = entry.getKey();
String[] values = entry.getValue();
System.out.println(name + ":" + Arrays.toString(values));
}
// ========== 获取请求行信息 ==========
// 5. 获取完整的请求URL
StringBuffer url = request.getRequestURL();
System.out.println("完整URL:" + url);
// 输出:http://localhost:8080/demo/requestDemo
// 6. 获取请求的URI
String uri = request.getRequestURI();
System.out.println("请求URI:" + uri);
// 输出:/demo/requestDemo
// 7. 获取请求行中的参数部分
String queryString = request.getQueryString();
System.out.println("参数部分:" + queryString);
// 输出:username=张三&hobby=篮球&hobby=足球
// 8. 获取请求方式
String method = request.getMethod();
System.out.println("请求方式:" + method);
// 9. 获取HTTP版本号
String protocol = request.getProtocol();
System.out.println("HTTP版本:" + protocol);
// 10. 获取webapp名字
String contextPath = request.getContextPath();
System.out.println("站点名:" + contextPath);
// 输出:/demo
}
}
四、使用时的注意事项
①getParameter和getParameterValues的区别
单选框、文本框这种只有一个值的,用getParameter。复选框这种可能有多个值的,必须用getParameterValues,否则只能拿到第一个。
②getParameterValues返回的是数组
哪怕只选中了一个复选框,返回的也是长度为1的数组,用之前最好判空。
③参数不存在时返回null
req.getParameter("不存在的参数") 返回的是null,不是空字符串。用的时候要注意空指针。
⑤getParameterMap返回的Map
key是参数名,value是String[]。哪怕参数只有一个值,也是数组。取值时要记得取第一个:
java
Map<String, String[]> map = request.getParameterMap();
String[] values = map.get("username");
String username = values[0];
⑥URL和URI的区别
-
URL:完整的网络地址,包含协议、域名、端口、路径
-
URI:只包含站点名和Servlet路径,不包含协议和域名
⑦getQueryString和getParameter的区别
-
getQueryString():获取原始的参数串,就是URL里?后面的原样内容,不解析
-
getParameter():获取解析后的参数值,根据参数名取值
java
// 请求:/test?name=张三&name=李四
String query = request.getQueryString(); // name=张三&name=李四(URL编码后的原始内容)
String[] names = request.getParameterValues("name"); // ["张三", "李四"](已自动解码)
⑧getRequestURL返回的是StringBuffer
如果要当作String用,需要调用toString()方法。
⑨getContextPath返回值带斜杠
比如项目名叫demo,返回的是/demo,不是demo。拼接路径时要注意不要重复加斜杠。
⑩GET请求才有QueryString
POST请求的参数在请求体里,getQueryString()返回null。如果想获取POST请求的参数,还是得用getParameter。
五、乱码问题
5.1 不同Tomcat版本的乱码表现
Tomcat版本不同,乱码的处理方式也不一样:
-
Tomcat 7及以下版本:GET和POST请求都有乱码问题。GET请求的URI默认用ISO-8859-1解码,POST请求的请求体也用ISO-8859-1解码。
-
Tomcat 8及以上版本:只有POST请求有乱码问题。GET请求的URI默认改成了UTF-8解码,一般不会乱码。
5.2 POST请求乱码
POST请求的参数在请求体里,不管哪个Tomcat版本,默认编码都是ISO-8859-1,不支持中文。不处理的话获取到的中文全是乱码。
解决方法:在获取任何参数之前,设置请求编码
java
// 这行代码必须在所有getParameter之前执行
request.setCharacterEncoding("UTF-8");
// 然后再获取参数
String username = request.getParameter("username");
这个设置只对POST请求有效,只影响请求体的解码方式。如果已经调用过getParameter再设置编码,那就来不及了。
5.3 GET请求乱码
GET请求的参数附在URL后面,乱码情况和Tomcat版本有关:
Tomcat 7及以下版本 :GET请求也有乱码。这时候request.setCharacterEncoding("UTF-8")对GET请求无效,因为GET请求的参数不在请求体里。
解决方法:修改Tomcat的server.xml配置文件,在Connector节点加上URIEncoding="UTF-8":
XML
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
Tomcat 8及以上版本:默认已经是UTF-8,不需要额外配置。如果因为某些原因改过配置导致乱码,同样用上面的方法改回来。
5.4 手动处理乱码(不推荐)
如果既不能改配置,又遇到了GET请求乱码,可以手动转码:
java
// 先用ISO-8859-1取出来,再转成UTF-8
name = new String(request.getParameter(name).getBytes("ISO-8859-1"), "UTF-8");
这种办法比较麻烦,每次获取都要手动转一次,不如直接配置编码来得省事。
写在最后
浏览器访问时,Tomcat根据URL找到对应的Servlet,调用service方法。我们可以通过HttpServletRequest获取请求参数和请求行信息,处理完业务逻辑后再通过HttpServletResponse返回响应数据。
以上是我对HttpServletRequest的学习整理,刚接触的时候也分不清这么多方法,写一遍代码跑一跑就慢慢记住了,希望对同样在学Servlet的你有点帮助。