Java Servlet请求案例:如何高效接收与处理HTTP请求(完整教程)
目录导读
- Servlet请求接收原理概述
- 环境搭建与基础配置
- GET请求接收实战
- POST请求接收与表单数据处理
- 请求参数解析:中文乱码解决方案
- 请求头信息获取与应用
- 综合案例:用户注册数据接收
- 常见问题与解答(FAQ)
Servlet请求接收原理概述
在Java Web开发中,Servlet作为服务端核心组件,负责接收客户端(通常是浏览器)发起的HTTP请求并生成响应,当用户点击链接、提交表单或通过AJAX发送数据时,Web容器(如Tomcat、Jetty)会将HTTP请求封装成HttpServletRequest对象,传递给对应的Servlet进行处理。

核心流程:
- 客户端发送HTTP请求 → Web容器解析 → 创建请求对象 → 调用Servlet的service()方法 → 根据请求类型分发到doGet()或doPost() → 开发者从request对象中提取数据
问答:为什么需要接收请求?
答:接收请求是Web应用与用户交互的入口,无论登录、搜索、提交订单都需要解析用户输入的数据,Servlet提供了标准化的API来获取参数、请求头、Cookie等信息。
环境搭建与基础配置
在开始编写请求接收代码前,确保你的开发环境已就绪:
工具要求:
- JDK 8+
- Tomcat 9+ 或 Jetty
- IDE(IntelliJ IDEA / Eclipse)
创建基础Servlet示例:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 这里实现请求接收逻辑
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("服务器已接收请求");
}
}
配置web.xml或使用注解后,访问http://localhost:8080/项目名/hello即可触发。
问答:@WebServlet注解和web.xml哪种方式更好?
答:两者功能等价,注解更适合单体应用,开发效率高;web.xml在大型项目或需要统一管理Servlet映射时更清晰,建议根据团队规范选择。
GET请求接收实战
GET请求参数通常附加在URL后面(如?name=小明&age=25),通过以下方法获取:
关键方法:
getParameter("参数名")— 获取单个参数getParameterValues("参数名")— 获取多值参数(如复选框)getParameterMap()— 获取所有参数封装为Map
代码示例:搜索功能
@WebServlet("/search")
public class SearchServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 获取单个参数
String keyword = request.getParameter("q");
String page = request.getParameter("page");
// 2. 获取多个值(checkbox选中的爱好)
String[] hobbies = request.getParameterValues("hobby");
// 3. 遍历所有参数
Map<String, String[]> params = request.getParameterMap();
for (Map.Entry<String, String[]> entry : params.entrySet()) {
System.out.println(entry.getKey() + " : " + Arrays.toString(entry.getValue()));
}
// 返回响应
response.getWriter().println("搜索关键词: " + keyword + ", 页码: " + page);
}
}
访问测试:
http://localhost:8080/demo/search?q=Servlet&page=2&hobby=reading&hobby=sports
问答:GET请求有长度限制吗?如何处理大参数?
答:GET请求URL长度通常限制在2048字节左右(浏览器和服务器共同限制),若参数较多或含大量文本,建议改用POST请求,或将参数编码后分段传输。
POST请求接收与表单数据处理
POST请求将参数放在请求体中,适合提交大量数据或敏感信息(如密码)。
标准表单提交示例:
<form action="/user/register" method="post">
用户名: <input type="text" name="username"><br>
密码: <input type="password" name="password"><br>
性别: <input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女<br>
<input type="submit" value="注册">
</form>
Servlet接收代码:
@WebServlet("/user/register")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); // 必加!防止中文乱码
String username = request.getParameter("username");
String password = request.getParameter("password");
String gender = request.getParameter("gender");
System.out.println("接收到的注册数据:");
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
System.out.println("性别: " + gender);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("注册成功!用户名:" + username);
}
}
问答:doPost和doGet如何选择?
答:GET用于获取资源(如搜索、查看),请求数据暴露在URL中;POST用于修改资源(如登录、注册、上传),数据在请求体中更安全,实际开发中请遵循RESTful规范。
请求参数解析:中文乱码解决方案
中文乱码是初学者最常遇到的问题,核心原因是编码不一致。
解决方案(二选一即可):
- 统一编码设置(推荐):
在doGet或doPost方法第一行添加:request.setCharacterEncoding("UTF-8"); - 单独解码参数(备用):
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");
注意:
setCharacterEncoding仅对POST请求生效,GET请求需在Tomcat配置(server.xml)中设置URIEncoding="UTF-8"- 前端表单页面也需使用UTF-8编码(
<meta charset="UTF-8">)
问答:为什么GET请求乱码要改Tomcat配置?
答:因为Tomcat默认用ISO-8859-1解码URL中的参数,而浏览器使用UTF-8编码,修改URIEncoding可以让Tomcat正确解码,或者通过request.getQueryString()获取原始查询字符串再手动解析。
请求头信息获取与应用
请求头包含客户端信息、缓存控制、认证令牌等数据,通过HttpServletRequest提供的API获取:
常用请求头示例:
@WebServlet("/headers")
public class HeaderServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取指定请求头
String userAgent = request.getHeader("User-Agent");
String referer = request.getHeader("Referer");
String contentType = request.getHeader("Content-Type");
// 获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String value = request.getHeader(name);
System.out.println(name + " : " + value);
}
response.getWriter().println("你的浏览器: " + userAgent);
}
}
实际应用场景:
- 通过
User-Agent判断设备类型(PC/手机),返回不同页面 - 通过
Referer进行防盗链 - 通过
Authorization头实现JWT令牌验证
问答:如何获取客户端IP地址?
答:使用request.getRemoteAddr(),若经过代理(如Nginx),需获取X-Forwarded-For头:String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.isEmpty()) { ip = request.getRemoteAddr(); }
综合案例:用户注册数据接收
将上述知识点整合为一个完整的用户注册案例,包含各种请求接收技巧:
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 设置编码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 2. 获取基本参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
String gender = request.getParameter("gender");
// 3. 获取多值参数(兴趣爱好)
String[] interests = request.getParameterValues("interest");
// 4. 获取请求头信息
String userAgent = request.getHeader("User-Agent");
String clientIp = request.getRemoteAddr();
// 5. 数据验证
if (username == null || username.trim().isEmpty()) {
out.println("<script>alert('用户名不能为空');history.back();</script>");
return;
}
// 6. 输出接收结果
out.println("<h2>注册信息接收成功</h2>");
out.println("用户名: " + username + "<br>");
out.println("邮箱: " + email + "<br>");
out.println("性别: " + gender + "<br>");
out.println("兴趣: " + Arrays.toString(interests) + "<br>");
out.println("客户端IP: " + clientIp + "<br>");
out.println("浏览器: " + userAgent + "<br>");
}
}
问答:这个案例能否用于生产环境?
答:需要增加密码加密(如BCrypt)、CSRF防护、输入过滤(防XSS)等安全措施,本案例仅用于演示请求接收方法,生产中请使用Spring MVC等框架简化开发并增强安全性。
常见问题与解答(FAQ)
Q1:为什么我获取的参数都是null?
A:检查以下三点:①请求URL和方法是否匹配(GET/POST);②表单控件必须有name属性;③Servlet映射路径是否正确(如@WebServlet("/test")而非/test/*)。
Q2:如何接收JSON格式的请求数据?
A:使用request.getReader()获取请求体字符流,然后用JSON库(如Jackson、Gson)解析:
BufferedReader reader = request.getReader();
StringBuilder json = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
json.append(line);
}
User user = new ObjectMapper().readValue(json.toString(), User.class);
Q3:GET和POST可以同时处理吗?
A:可以,重写service()方法,或使用@Override注解中的doGet和doPost方法,即可同时处理两种请求。
Q4:请求参数太多怎么办?
A:超过10个参数建议使用JavaBean封装,配合BeanUtils工具类自动注入:
User user = new User(); BeanUtils.populate(user, request.getParameterMap());
Q5:如何防止参数注入攻击?
A:①使用PreparedStatement替代Statement;②对用户输入进行HTML编码(如使用StringEscapeUtils.escapeHtml4());③限制参数长度和类型。
通过本文的详细案例,你应该已掌握Servlet接收HTTP请求的完整方法,从基础参数获取到复杂JSON解析,再到安全注意事项,这些知识是构建Java Web应用的基础,建议在实际项目中结合Spring MVC等框架使用,但理解底层Servlet原理将帮助你更好地调试和优化问题。