文章目录
- 一、先搞清楚我们要做什么
- 二、环境准备
- 三、第一步:写测试页面 index.html
- 四、第二步:写 Servlet —— DemoTestServlet.java
- 代码里三个必须看懂的点
- 五、三种方式逐个实测
- 方式①:GET 表单提交
- 方式②:超链接访问(本质也是 GET)
- 方式③:POST 表单提交(重点看 F12)
- 六、一个请求从浏览器到 Servlet,经历了什么
- 七、GET vs POST:结合这次实验的硬核对比
- 八、新手必踩的 5 个坑(对照排查)
- 坑 1:提交完页面一片空白(最常见)
- 坑 2:405 Method Not Allowed
- 坑 3:404 Not Found
- 坑 4:POST 提交中文变问号/乱码
- 坑 5:路径写死,换个部署名就挂
- 九、面试 30 秒速答版
- 附录:web.xml 配置方式(不用注解时)
- 写在最后
面试天天被问「GET 和 POST 有什么区别」,你背得出「GET 参数在 URL,POST 参数在请求体」,但你亲手传过一次参数吗?
这篇文章用一个最小到不能再小的实验,把GET 表单、超链接、POST 表单三种提交方式全部跑通,再打开 F12 亲眼看看参数到底去了哪里。代码全部可直接复制运行,看完你就能在面试里把这道题讲出画面感。
一、先搞清楚我们要做什么
我们要写一个 Web 应用,上下文路径(contextPath)叫/servletApp,里面放一个 Servlet,映射到/demoTest。然后在一个测试页面上准备三种「递话」给这个 Servlet 的方式:
| 方式 | 提交方法 | 参数出现在哪 |
|---|---|---|
| ① GET 表单提交 | GET | 地址栏 URL 的?msg=xxx |
| ② 超链接访问 | GET(本质) | 地址栏 URL 的?msg=hello |
| ③ POST 表单提交 | POST | 请求体 Form Data,地址栏不变 |
浏览器访问地址统一是:
http://127.0.0.1:8080/servletApp/demoTest为什么要一次测三种?因为初学者最容易误以为「只有表单才能传参数」。实际上超链接、地址栏手动输入、JS 发请求,走的都是 GET;而 POST 基本只来自
method="post"的表单(或 AJAX)。一次把它们放一起对比,区别一眼就懂。
二、环境准备
- IDEA(Community 版即可)+ 本地 Tomcat 9.x
- JDK 8 及以上
- 本文使用
javax.servlet(对应 Tomcat 9)。如果你用 Tomcat 10+,把javax.servlet全部换成jakarta.servlet即可,代码逻辑完全一样。
项目结构(传统 JavaWeb 工程,也可以用 Maven,依赖见文末附录):
servletApp ├── src │ └── com.example.servlet │ └── DemoTestServlet.java └── web ├── WEB-INF │ └── web.xml(使用注解可省略) └── index.html三、第一步:写测试页面 index.html
页面上放三个区块:GET 表单、超链接、POST 表单。注意两个表单的action都要带上上下文路径/servletApp。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>Servlet 请求测试(/servletApp/demoTest)</title></head><body><h2>Servlet 请求测试(/servletApp/demoTest)</h2><h3>GET 表单提交</h3><formaction="/servletApp/demoTest"method="get"><inputtype="text"name="msg"placeholder="输入内容"><buttontype="submit">GET 提交</button></form><h3>超链接访问(GET)</h3><ahref="/servletApp/demoTest?msg=hello">访问 /servletApp/demoTest?msg=hello</a><h3>POST 表单提交</h3><formaction="/servletApp/demoTest"method="post"><inputtype="text"name="msg"placeholder="输入内容"><buttontype="submit">POST 提交</button></form></body></html>关键点:输入框的name="msg"就是参数名,Servlet 里靠这个名字取值。表单method决定了这次请求是 GET 还是 POST。
四、第二步:写 Servlet —— DemoTestServlet.java
让doGet和doPost都调用同一个handleRequest,这样三种方式进来的参数都能用同一套代码接收和响应,避免写两遍。
packagecom.example.servlet;importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.io.PrintWriter;@WebServlet("/demoTest")publicclassDemoTestServletextendsHttpServlet{// GET 请求走这里<