HttpServletResponse源码解析

发布于:2025-06-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

Java Servlet API 中 HttpServletResponse 接口的源码,这是 Java Web 开发中非常核心的一个接口,用于向客户端(通常是浏览器)发送 HTTP 响应


public interface HttpServletResponse extends ServletResponse {
    int SC_CONTINUE = 100;
    int SC_SWITCHING_PROTOCOLS = 101;
    int SC_OK = 200;
    int SC_CREATED = 201;
    int SC_ACCEPTED = 202;
    int SC_NON_AUTHORITATIVE_INFORMATION = 203;
    int SC_NO_CONTENT = 204;
    int SC_RESET_CONTENT = 205;
    int SC_PARTIAL_CONTENT = 206;
    int SC_MULTIPLE_CHOICES = 300;
    int SC_MOVED_PERMANENTLY = 301;
    int SC_MOVED_TEMPORARILY = 302;
    int SC_FOUND = 302;
    int SC_SEE_OTHER = 303;
    int SC_NOT_MODIFIED = 304;
    int SC_USE_PROXY = 305;
    int SC_TEMPORARY_REDIRECT = 307;
    int SC_BAD_REQUEST = 400;
    int SC_UNAUTHORIZED = 401;
    int SC_PAYMENT_REQUIRED = 402;
    int SC_FORBIDDEN = 403;
    int SC_NOT_FOUND = 404;
    int SC_METHOD_NOT_ALLOWED = 405;
    int SC_NOT_ACCEPTABLE = 406;
    int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
    int SC_REQUEST_TIMEOUT = 408;
    int SC_CONFLICT = 409;
    int SC_GONE = 410;
    int SC_LENGTH_REQUIRED = 411;
    int SC_PRECONDITION_FAILED = 412;
    int SC_REQUEST_ENTITY_TOO_LARGE = 413;
    int SC_REQUEST_URI_TOO_LONG = 414;
    int SC_UNSUPPORTED_MEDIA_TYPE = 415;
    int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    int SC_EXPECTATION_FAILED = 417;
    int SC_INTERNAL_SERVER_ERROR = 500;
    int SC_NOT_IMPLEMENTED = 501;
    int SC_BAD_GATEWAY = 502;
    int SC_SERVICE_UNAVAILABLE = 503;
    int SC_GATEWAY_TIMEOUT = 504;
    int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

    void addCookie(Cookie var1);

    boolean containsHeader(String var1);

    String encodeURL(String var1);

    String encodeRedirectURL(String var1);

    /** @deprecated */
    @Deprecated
    String encodeUrl(String var1);

    /** @deprecated */
    @Deprecated
    String encodeRedirectUrl(String var1);

    void sendError(int var1, String var2) throws IOException;

    void sendError(int var1) throws IOException;

    void sendRedirect(String var1) throws IOException;

    void setDateHeader(String var1, long var2);

    void addDateHeader(String var1, long var2);

    void setHeader(String var1, String var2);

    void addHeader(String var1, String var2);

    void setIntHeader(String var1, int var2);

    void addIntHeader(String var1, int var2);

    void setStatus(int var1);

    /** @deprecated */
    @Deprecated
    void setStatus(int var1, String var2);

    int getStatus();

    String getHeader(String var1);

    Collection<String> getHeaders(String var1);

    Collection<String> getHeaderNames();

    default void setTrailerFields(Supplier<Map<String, String>> supplier) {
    }

    default Supplier<Map<String, String>> getTrailerFields() {
        return null;
    }
}


🧩 一、作用概述

HttpServletResponseServletResponse 的子接口,专门用于处理 HTTP 协议的响应内容。在 Servlet 中,当服务器收到请求后,会创建一个 HttpServletRequest 对象封装请求信息,同时也会创建一个 HttpServletResponse 对象来构建响应内容。

开发者可以通过这个对象:

  • 设置响应状态码
  • 添加响应头(Headers)
  • 写入响应体(Body)
  • 发送重定向
  • 添加 Cookie 等

📌 二、主要常量:HTTP 状态码

该接口定义了大量常用的 HTTP 状态码常量,方便开发者直接使用,例如:

状态码常量 含义
SC_OK (200) 请求成功
SC_FOUND (302) 临时重定向
SC_NOT_FOUND (404) 资源未找到
SC_INTERNAL_SERVER_ERROR (500) 服务器内部错误
SC_FORBIDDEN (403) 拒绝访问
SC_UNAUTHORIZED (401) 未授权

这些状态码可以直接通过 response.setStatus(HttpServletResponse.SC_OK); 来设置。


🛠️ 三、常用方法详解

1. 设置响应状态码

void setStatus(int sc);

设置响应的状态码,比如 200、404 等。

⚠️ 注意:setStatus(int, String) 方法已被废弃。


2. 发送错误响应

void sendError(int sc) throws IOException;
void sendError(int sc, String msg) throws IOException;

发送错误状态码给客户端,并可选地附带错误消息。

示例:

response.sendError(HttpServletResponse.SC_NOT_FOUND, "资源不存在");

3. 重定向

void sendRedirect(String location) throws IOException;

让浏览器跳转到新的 URL(会发起一个新的请求)。

示例:

response.sendRedirect("http://example.com");

4. 添加/设置响应头

void setHeader(String name, String value);
void addHeader(String name, String value);
void setDateHeader(String name, long date);
void setIntHeader(String name, int value);
  • setHeader():覆盖已有的 header。
  • addHeader():追加 header(可以有多个相同名称的 header)。

示例:

response.setHeader("Content-Type", "text/html;charset=utf-8");
response.setIntHeader("Refresh", 5); // 每5秒刷新一次页面

5. 添加 Cookie

void addCookie(Cookie cookie);

示例:

Cookie cookie = new Cookie("user", "Tom");
cookie.setMaxAge(60 * 60 * 24); // 一天有效期
response.addCookie(cookie);

6. URL 编码(用于会话跟踪)

String encodeURL(String url);
String encodeRedirectURL(String url);

用于对 URL 进行编码,以支持 Session ID 的追踪(如 Cookie 被禁用时)。

示例:

String encodedUrl = response.encodeURL("index.jsp");

⚠️ 已废弃的方法:

@Deprecated
String encodeUrl(String url);
String encodeRedirectUrl(String url);

7. 获取和设置 Trailer Fields(HTTP 1.1 分块传输尾部字段)

default void setTrailerFields(Supplier<Map<String, String>> supplier) {}
default Supplier<Map<String, String>> getTrailerFields() { return null; }

用于在分块传输(chunked transfer)结束后发送一些额外的头部信息(trailer headers),但实际使用较少。


8. 检查是否已经包含某个 Header

boolean containsHeader(String name);

返回当前响应是否已经设置了指定名称的 header。


📁 四、常见使用场景举例

✅ 场景 1:返回 JSON 数据

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/json;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.print("{\"message\": \"Hello World\"}");
}

✅ 场景 2:重定向到另一个页面

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.sendRedirect("/success.html");
}

✅ 场景 3:下载文件

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=\"test.txt\"");
    
    // 写入文件内容到输出流
    OutputStream out = response.getOutputStream();
    out.write("This is the file content".getBytes());
    out.flush();
}

📚 五、与 Spring MVC 的关系

在 Spring MVC 中,虽然我们很少直接操作 HttpServletResponse,但底层依然是基于它实现的。Spring 提供了更高层的抽象,如:

  • @ResponseBody
  • ResponseEntity<T>
  • HttpServletResponse 作为控制器方法参数传入

例如:

@GetMapping("/data")
public ResponseEntity<String> getData() {
    return ResponseEntity.ok("Hello");
}

或者:

@GetMapping("/download")
public void downloadFile(HttpServletResponse response) throws IOException {
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=file.pdf");
    // 写入 PDF 文件内容到 response.getOutputStream()
}

🔐 六、注意事项

项目 建议
不要多次调用 getWriter()getOutputStream() 两者不能共用,否则抛出 IllegalStateException
设置 ContentType 应该尽早 防止乱码问题
避免在异步或过滤器链中提前提交响应 否则后续逻辑将无法执行
sendRedirect 之后应 return 避免继续执行代码造成异常

🧠 总结

HttpServletResponse 是 Java Web 开发中控制 HTTP 响应的核心接口,掌握它可以让我们更灵活地处理以下内容:

  • 返回数据(JSON、HTML、文件等)
  • 控制浏览器行为(重定向、缓存、刷新)
  • 安全控制(设置 Headers、Cookie)


网站公告

今日签到

点亮在社区的每一天
去签到