接收请求:HttpServletRequest的几种用法

当浏览器访问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的你有点帮助。

相关推荐
子兮曰14 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰14 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万14 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝14 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋15 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁16 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王952717 小时前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大18 小时前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师18 小时前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学18 小时前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端