文章目录
- 今日实验目标(老师划的重点)
- 一、先搞懂:HTTP 请求到底分几块?
- 二、RequestDemo1:获取请求行 + 请求头
- 2.1 在 myServlet 包下新建 RequestDemo1
- 2.2 完整代码(直接抄)
- 2.3 启动服务器,浏览器访问
- 2.4 请求头:拿到浏览器版本
- 三、RequestDemo2:获取请求体(POST 才有!)
- ⚠️ 一个重要的坑
- 3.1 整体思路
- 3.2 第一步:在 web 目录下新建 register.html
- 3.3 第二步:新建 RequestDemo2,在 doPost 里读请求体
- 3.4 启动服务器,访问测试
- 四、今日 API 速查表(建议截图保存)
- 五、今日踩坑提醒(老师反复强调)
- 六、写在最后
哈喽各位小伙伴,今天是我学 JavaWeb 的第 N 天,跟着老师把Request 对象从头到尾捋了一遍。
这玩意儿说简单也简单,说坑也真坑——GET 没请求体、POST 中文乱码、URI 和 URL 傻傻分不清楚……
这篇文章把我今天上课敲的所有代码、控制台截图、老师强调的重点全给你们整理出来了,看完直接能跑,建议先收藏再看!
今日实验目标(老师划的重点)
| 序号 | 目标 | 是否重点 |
|---|---|---|
| 1 | 学会通过继承HttpServlet创建自己的 Servlet 类 | ⭐ |
| 2 | 知道doGet和doPost方法什么时候被调用 | ⭐⭐ |
| 3 | 知道如何在 Servlet 中获取 HTTP 请求参数、如何向用户发回响应 | ⭐⭐ |
| 4 | 解决请求和响应中的中文乱码问题 | ⭐⭐⭐ 重点/难点 |
| 5 | 知道如何把表单提交给一个 Servlet 处理 | ⭐⭐ |
| 6 | 知道如何在HttpServlet子类中获取ServletContext对象 | ⭐ |
本次实验不用新建工程,直接在已经创建好的
servletApp工程里搞就行。
一、先搞懂:HTTP 请求到底分几块?
浏览器给服务器发请求,本质上就是发了一坨文本。这坨文本一共分三部分:
┌─────────────────────────────────────────────┐ │ ① 请求行 (Request Line) │ ← GET /servletApp/RequestDemo1 HTTP/1.1 ├─────────────────────────────────────────────┤ │ ② 请求头 (Request Headers) │ ← User-Agent、Host、Accept... ├─────────────────────────────────────────────┤ │ ③ 请求体 (Request Body) │ ← 只有 POST 才有,GET 没有! │ username=xp&password=123 │ └─────────────────────────────────────────────┘而HttpServletRequest对象,就是 Tomcat 把这坨文本封装好塞给你的一个 Java 对象——你想拿什么,调对应的方法就行。
二、RequestDemo1:获取请求行 + 请求头
2.1 在 myServlet 包下新建 RequestDemo1
操作步骤:
- 在
myServlet文件夹上右键 → New → Servlet - 类名输入:
RequestDemo1 - 父类选
HttpServlet,其他默认
2.2 完整代码(直接抄)
packagemyServlet;importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;/** * 使用 Request 获取请求行数据(GET 方式) * HttpServletRequest 对象用于封装客户端的请求信息 */@WebServlet("/RequestDemo1")publicclassRequestDemo1extendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{System.out.println("访问 RequestDemo1");// 1. 获取请求行中的请求方法,例如 GET 或 POSTStringmethod=req.getMethod();System.out.println("Request Method: "+method);// 2. 获取虚拟目录(项目访问路径,在 Tomcat 里设置):例如 /servletAppStringcontextPath=req.getContextPath();System.out.println("Context Path: "+contextPath);// 3. 获取 Servlet 路径:/RequestDemo1StringservletPath=req.getServletPath();System.out.println("Servlet Path: "+servletPath);// 4. 获取请求行中的参数(GET 方式):?username=zhangsanStringqueryString=req.getQueryString();System.out.println("Query String: "+queryString);// 5. 获取请求 URL(统一资源定位符):// http://localhost:8080/servletApp/RequestDemo1StringrequestURL=req.getRequestURL().toString();System.out.println("Request URL: "+requestURL);// 6. 获取请求 URI(统一资源标识符):/servletApp/RequestDemo1StringrequestURI=req.getRequestURI();System.out.println("Request URI: "+requestURI);// 7. 获取请求头 user-agent:浏览器的版本信息Stringagent=req.getHeader("user-agent");System.out.println(agent);}@OverrideprotectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{doGet(req,resp);}}代码截图长这样(就是老师上课敲的版本)👇
2.3 启动服务器,浏览器访问
在浏览器地址栏输入:
http://localhost:8080/servletApp/RequestDemo1?username=zhangsan控制台输出结果👇
我们来对着结果一行行读:
Request Method: GET ← 我是 GET 请求 Context Path: /servletApp ← 项目的虚拟目录 Servlet Path: /RequestDemo1 ← 我这个 Servlet 的路径 Request URL: http://localhost:8080/servletApp/RequestDemo1 ← 完整 URL Request URI: /servletApp/RequestDemo1 ← URI(没有协议和主机) Query String: username=zhangsan ← 问号后面那一串URL 和 URI 的区别(面试必问):
- URL= 协议 + 主机 + 端口 + 路径(能定位到一台具体的服务器资源)
- URI= 路径部分(不包含协议、主机、端口),范围更大
- 一句话:URL 是 URI 的子集,能当网址点的那个就是 URL。
2.4 请求头:拿到浏览器版本
// 获取请求头 user-agent:浏览器的版本信息Stringagent=req.getHeader("user-agent");System.out.println(agent);重启服务后控制台会打印出类似这一串:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36这玩意儿有啥用?可以用来判断用户用的是 Chrome、Edge 还是手机浏览器,然后给不同的页面做适配。
三、RequestDemo2:获取请求体(POST 才有!)
⚠️ 一个重要的坑
GET 请求是没有请求体的!参数直接拼在 URL 后面(就是
getQueryString()拿到的那串)。
想拿请求体,必须把请求方式改成POST。
3.1 整体思路
- 准备一个 HTML 页面,里面放一个
<form>表单,用来发 POST 请求; - 在 Servlet 的
doPost方法里获取请求体数据; - 用
request.getReader()或者request.getInputStream()读出来; - 启动服务器访问测试。
3.2 第一步:在 web 目录下新建 register.html
路径:WebContent/register.html(或者 Maven 工程里的webapp/register.html)
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>注册页面</title></head><body><!-- action: form 表单提交的请求地址 method: 请求方式,指定为 post --><formaction="/servletApp/RequestDemo2"method="post"><inputtype="text"name="username"><inputtype="password"name="password"><inputtype="submit"></form></body></html>💡 划重点:
action里写的是Servlet 的访问路径,要跟@WebServlet里的一模一样;method="post"一定要写,不写默认就是 GET;- 每个 input 的
name属性就是后端拿到的参数名。
3.3 第二步:新建 RequestDemo2,在 doPost 里读请求体
packagemyServlet;importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.BufferedReader;importjava.io.IOException;/** * 使用 Request 获取请求体数据 * HttpServletRequest 对象用于封装客户端的请求信息 */@WebServlet("/RequestDemo2")publicclassRequestDemo2extendsHttpServlet{@OverrideprotectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{// 获取 post 请求体:请求参数// 1. 获取字符输入流BufferedReaderbr=request.getReader();// 2. 读取数据Stringline=br.readLine();System.out.println(line);}@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doPost(request,response);}}而不是getInputStream()?
getReader():拿字符流,适合读文本(比如表单提交的username=xp&password=123);getInputStream():拿字节流,适合读文件上传这种二进制数据。
我们现在传的是纯文本,所以用getReader()就够了。
3.4 启动服务器,访问测试
浏览器打开:
http://localhost:8080/servletApp/register.html在表单里随便输入(比如用户名xp、密码123),点提交。
控制台就会打印出:
username=xp&password=123这就是请求体的原始模样——一行字符串,&分隔多个参数,=连接键值。
四、今日 API 速查表(建议截图保存)
| 方法 | 作用 | 示例返回值 |
|---|---|---|
req.getMethod() | 获取请求方式 | GET/POST |
req.getContextPath() | 获取虚拟目录(项目路径) | /servletApp |
req.getServletPath() | 获取 Servlet 路径 | /RequestDemo1 |
req.getQueryString() | 获取 GET 请求参数串 | username=zhangsan |
req.getRequestURL() | 获取完整 URL(StringBuffer) | http://localhost:8080/servletApp/RequestDemo1 |
req.getRequestURI() | 获取 URI(不含协议主机) | /servletApp/RequestDemo1 |
req.getHeader("User-Agent") | 获取指定请求头 | 浏览器版本字符串 |
req.getReader() | 获取字符输入流(读请求体) | BufferedReader |
req.getInputStream() | 获取字节输入流(读文件等) | ServletInputStream |
五、今日踩坑提醒(老师反复强调)
GET 没有请求体,
getReader()/getInputStream()只能在 POST 里用;getRequestURL()返回的是StringBuffer,想打印一定要.toString();getQueryString()在没有参数时返回null,不是空字符串,判空要注意;中文乱码是重难点:POST 提交中文参数时,记得在
doPost第一行加:request.setCharacterEncoding("UTF-8");否则控制台拿到的可能是一坨
???";表单的
action路径写错,404 找不到 Servlet,检查一下是不是少写了虚拟目录/servletApp。
六、写在最后
今天这节课其实就是一句话:浏览器发过来的所有东西,Tomcat 都封装进了request对象,你想拿啥就调啥方法。
- 请求行 →
getMethod / getContextPath / getRequestURI / getQueryString - 请求头 →
getHeader("xxx") - 请求体 →
getReader() / getInputStream()(POST 专属)
下节课老师要讲请求参数的通用获取方式(getParameter、getParameterMap),还有请求转发和响应重定向,咱们到时候继续肝!
如果这篇文章帮到你了,麻烦点赞 + 收藏 + 关注走一波,咱们下节课见 👋
标签:JavaWebServletHttpServletRequestRequestJava后端学习笔记乱码