httpservletrequest和httpservletresponse是tomcat自动创建的http请求与响应封装对象,分别用于完整读取请求行/头/体、设置响应状态码/头/体;二者操作均需在响应提交前完成,且注意流与参数方法不可混用。

Java 中通过 HttpServletRequest 和 HttpServletResponse 操作原生 HTTP 报文,本质是借助 Servlet API 对底层 HTTP 协议的抽象封装——你无法直接读写裸字节流(如 TCP 层原始报文),但能完整访问和控制 HTTP 请求行、请求头、请求体、响应状态行、响应头、响应体等关键部分。
读取请求报文:解析方法、路径、头、参数与正文
HttpServletRequest 提供了语义化方法来提取 HTTP 请求各组成部分:
-
请求行信息:用
getMethod()获取GET/POST等方法;getRequestURI()或getRequestURL()获取路径或完整 URL;getProtocol()得到HTTP/1.1 -
请求头字段:用
getHeader("User-Agent")读单个头;getHeaders("Accept")获取多值头(如多个Accept);getHeaderNames()遍历所有头名 -
请求参数(Query String / Form Data):对
GET或POST application/x-www-form-urlencoded,直接调getParameter("name");注意:该方法会自动解码并合并同名参数,且仅在首次调用时解析请求体(后续调用缓存结果) -
原始请求体(Body):需用
getInputStream()(二进制)或getReader()(字符流)。⚠️ 注意:getParameter*方法内部已消费了 body 流,若先调用了它们,再读流可能返回空——应避免混用。适合处理application/json、application/xml等非表单格式
写入响应报文:设置状态码、头、Cookie 与响应体
HttpServletResponse 允许你精确构造 HTTP 响应的每个环节:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
状态码与原因短语:用
setStatus(404)或更规范的sendError(404, "Not Found")(后者会自动设置状态行并输出默认错误页) -
响应头字段:用
setHeader("Content-Type", "application/json; charset=utf-8");若允许多次设置同一头(如多个Set-Cookie),用addHeader()或更推荐的addCookie(Cookie) -
Cookie 管理:创建
new Cookie("key", "value"),设置setPath("/")、setMaxAge(3600)、setHttpOnly(true)后,传给addCookie() -
响应体输出:优先使用
getWriter()(返回PrintWriter,适合文本)或getOutputStream()(返回ServletOutputStream,适合二进制)。二者不可混用,否则抛IllegalStateException
注意字符编码与内容类型的一致性
HTTP 报文的可读性高度依赖编码声明是否匹配实际字节序列:
- 设置响应内容类型时,务必显式指定字符集:
response.setContentType("text/html; charset=UTF-8"),否则浏览器可能按 ISO-8859-1 解析中文而乱码 - 调用
response.getWriter()前,应先设编码:response.setCharacterEncoding("UTF-8");也可合并为response.setContentType("text/plain; charset=UTF-8"),它会同时设置 Content-Type 头和 Writer 编码 - 对于请求体(如 JSON),需从
request.getCharacterEncoding()获取客户端声明的编码,若为空则按规范默认为ISO-8859-1,常需手动转 UTF-8(尤其 POST 表单未声明accept-charset时)
绕过容器默认行为:禁用缓冲、强制提交、重定向控制
某些场景需干预 Servlet 容器的默认响应流程:
-
立即发送响应(不缓冲):调用
response.flushBuffer()强制将已写入缓冲区的内容发往客户端;response.reset()可清空已设置的状态码与头(仅限未提交前) -
重定向 vs 转发:用
response.sendRedirect("/login")发起 302 重定向(客户端发起新请求);用request.getRequestDispatcher("/error.jsp").forward(request, response)是服务端内部转发(URL 不变,请求对象复用) -
禁止缓存敏感响应:添加头
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate")、Pragma: no-cache、Expires: 0
不复杂但容易忽略的是:所有操作都必须在响应被提交(committed)前完成。一旦调用过 flushBuffer() 或响应体已写出足够字节数(取决于容器缓冲区大小),再尝试修改状态码或响应头就会失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










