
1. Servlet 客户端 HTTP 请求概述在Java Web开发中Servlet作为处理HTTP请求的核心组件其客户端请求处理能力直接决定了Web应用的交互质量。我经历过不少项目发现很多开发者对Servlet处理HTTP请求的细节掌握不够深入导致后期出现各种性能问题和安全隐患。Servlet客户端HTTP请求处理主要涉及请求解析、参数获取、头部信息读取、内容类型判断等核心功能。一个典型的Servlet处理流程是这样的当客户端浏览器、移动App或其他服务发起HTTP请求时Web容器如Tomcat会创建HttpServletRequest对象这个对象封装了所有的请求信息然后交给对应的Servlet进行处理。关键点HttpServletRequest对象是线程不安全的这意味着在Servlet中定义的实例变量可能引发并发问题。我在实际项目中就遇到过因为忽略这一点而导致的数据错乱bug。2. HTTP请求核心要素解析2.1 请求方法与使用场景HTTP/1.1定义了八种主要方法但在Servlet开发中最常用的是以下四种GET用于获取资源参数显示在URL中示例商品列表查询、用户信息获取特点可缓存、有长度限制POST用于提交数据示例表单提交、文件上传特点请求体传输、无长度限制PUT用于更新完整资源示例用户资料全量更新特点幂等性操作DELETE用于删除资源示例删除订单、移除收藏在Servlet中获取请求方法很简单String method request.getMethod();2.2 请求头信息处理HTTP头信息包含了客户端环境、缓存策略、内容协商等重要信息。常见的需要处理的头信息包括User-Agent客户端类型和版本Accept客户端可接受的内容类型Content-Type请求体的媒体类型Cookie客户端存储的会话信息获取特定头信息的代码示例String userAgent request.getHeader(User-Agent); String contentType request.getContentType();经验之谈处理移动端请求时User-Agent的判断要特别小心。不同厂商的UA格式差异很大建议使用成熟的解析库而不是自己写正则表达式。2.3 请求参数获取技巧Servlet提供了多种获取参数的方式各有适用场景getParameter()获取单个参数值String username request.getParameter(username);getParameterValues()获取多值参数如复选框String[] hobbies request.getParameterValues(hobby);getParameterMap()获取所有参数的Map视图MapString, String[] paramMap request.getParameterMap();参数编码问题是个常见坑点。我建议在获取参数前统一设置编码request.setCharacterEncoding(UTF-8);3. 请求体内容处理实战3.1 表单数据处理对于application/x-www-form-urlencoded类型的表单数据可以直接使用getParameter方法获取。但需要注意POST请求的参数不在URL中但仍然受服务器配置的大小限制文件上传需要使用multipart/form-data类型3.2 JSON请求体解析现代应用常用JSON作为数据交换格式。处理JSON请求的典型流程获取输入流读取并解析JSON转换为Java对象示例代码BufferedReader reader request.getReader(); StringBuilder sb new StringBuilder(); String line; while ((line reader.readLine()) ! null) { sb.append(line); } JSONObject json new JSONObject(sb.toString());性能提示对于大JSON数据考虑使用流式解析器如Jackson的JsonParser而非一次性读取全部内容。3.3 文件上传处理文件上传需要使用multipart/form-data编码。Servlet 3.0提供了更简洁的APIPart filePart request.getPart(file); String fileName filePart.getSubmittedFileName(); InputStream fileContent filePart.getInputStream(); // 保存文件到指定位置 Files.copy(fileContent, Paths.get(/uploads/ fileName));常见问题排查确保表单有enctypemultipart/form-data属性检查服务器配置的max-file-size和max-request-size临时目录要有写入权限4. 高级特性与性能优化4.1 异步请求处理Servlet 3.0引入了异步处理能力适合长时间运行的操作WebServlet(urlPatterns /async, asyncSupported true) public class AsyncServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { AsyncContext asyncContext request.startAsync(); CompletableFuture.runAsync(() - { // 长时间任务 asyncContext.getResponse().getWriter().write(Done); asyncContext.complete(); }); } }4.2 请求转发与包含Servlet之间可以通过转发(forward)和包含(include)协作// 转发到另一个Servlet request.getRequestDispatcher(/other).forward(request, response); // 包含另一个Servlet的输出 request.getRequestDispatcher(/header).include(request, response);区别在于转发完全移交控制权当前Servlet不应再输出包含将目标Servlet的输出包含到当前响应中4.3 性能优化技巧输入流复用避免多次读取request.getInputStream()参数缓存对于频繁访问的参数可缓存到局部变量线程池配置调整Web容器的线程池大小启用压缩配置服务器对响应进行Gzip压缩5. 常见问题排查手册5.1 502 Bad Gateway错误这类错误通常出现在以下场景后端服务无响应代理服务器配置错误请求超时排查步骤检查后端服务是否正常运行查看服务器日志中的详细错误信息测试直接访问后端服务是否正常5.2 500 Internal Server Error常见原因未捕获的运行时异常数据库连接失败空指针异常调试方法try { // 业务代码 } catch (Exception e) { e.printStackTrace(response.getWriter()); }5.3 中文乱码问题全方位解决方案设置请求编码request.setCharacterEncoding(UTF-8)设置响应编码response.setContentType(text/html;charsetUTF-8)检查数据库连接字符串是否指定了字符集确保所有文本文件以UTF-8编码保存6. 安全防护最佳实践6.1 输入验证所有客户端输入都应视为不可信的// 防XSS过滤 String safeInput StringEscapeUtils.escapeHtml4(request.getParameter(input)); // 防SQL注入 PreparedStatement stmt conn.prepareStatement(SELECT * FROM users WHERE id?); stmt.setString(1, request.getParameter(id));6.2 CSRF防护Spring Security等框架提供了CSRF防护手动实现也很简单// 生成Token String csrfToken UUID.randomUUID().toString(); session.setAttribute(csrfToken, csrfToken); // 验证Token if (!csrfToken.equals(request.getParameter(csrfToken))) { throw new SecurityException(CSRF验证失败); }6.3 敏感信息保护密码等敏感信息必须加密存储使用BCrypt等强哈希算法会话ID要设置为HttpOnly和Secure生产环境关闭详细错误信息在Servlet中配置安全响应头response.setHeader(X-Content-Type-Options, nosniff); response.setHeader(X-Frame-Options, DENY); response.setHeader(X-XSS-Protection, 1; modeblock);7. 现代Servlet开发演进虽然现在流行Spring Boot等框架但理解Servlet底层原理仍然很重要。一些发展趋势注解取代web.xmlWebServlet等注解简化配置非阻塞IOServlet 3.1的ReadListener/WriteListenerHTTP/2支持需要服务器和客户端共同支持反应式编程与Servlet异步特性结合示例非阻塞读取ServletInputStream input request.getInputStream(); input.setReadListener(new ReadListener() { public void onDataAvailable() throws IOException { // 数据可读时回调 } // 其他回调方法... });我在实际项目中发现合理使用Servlet的异步特性可以将吞吐量提升30%以上特别是在处理大量慢速客户端连接时效果显著。