杰瑞科技汇

Java如何构建标准HTTP响应?

  1. Servlet 原生 API:这是最基础的方式,理解它有助于你掌握底层原理。
  2. Spring Boot 框架:这是目前业界最主流、最简单高效的方式。

我会分别对这两种方式进行详细说明。

Java如何构建标准HTTP响应?-图1
(图片来源网络,侵删)

Servlet 原生 API 方式

在标准的 Java Web 开发中,我们通过 HttpServletResponse 对象来设置响应。

核心方法

HttpServletResponse 提供了以下几类核心方法来构建响应:

  • 设置状态码: setStatus(int sc)
  • 设置响应头: setHeader(String name, String value)
  • 设置响应体(正文): getWriter() (用于文本) 或 getOutputStream() (用于二进制,如图片、文件)
  • 重定向: sendRedirect(String location)

示例 1:返回纯文本

这是最简单的响应,直接将字符串写回给客户端。

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/textResponse")
public class TextResponseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 设置响应内容类型和字符编码,防止中文乱码
        response.setContentType("text/plain;charset=UTF-8");
        // 2. 获取输出流,并写入内容
        response.getWriter().write("这是一个来自 Servlet 的纯文本响应!");
    }
}

访问 http://yourserver:port/yourApp/textResponse,浏览器会显示: 这是一个来自 Servlet 的纯文本响应!

Java如何构建标准HTTP响应?-图2
(图片来源网络,侵删)

示例 2:返回 JSON 数据(RESTful API 的核心)

返回 JSON 是现代 Web 开发中最常见的场景,你需要手动将 Java 对象转换为 JSON 字符串。

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import com.google.gson.Gson; // 需要引入 Gson 或 Jackson 等库
@WebServlet("/jsonResponse")
public class JsonResponseServlet extends HttpServlet {
    // 使用 Gson 库进行对象到 JSON 的转换
    private final Gson gson = new Gson();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 设置响应内容类型为 JSON
        response.setContentType("application/json;charset=UTF-8");
        // 2. 创建一个 Java 对象作为响应数据
        User user = new User("张三", 30, "zhangsan@example.com");
        // 3. 将 Java 对象转换为 JSON 字符串
        String jsonString = gson.toJson(user);
        // 4. 将 JSON 字符串写入响应流
        response.getWriter().write(jsonString);
    }
    // 定义一个简单的 User 类
    static class User {
        private String name;
        private int age;
        private String email;
        public User(String name, int age, String email) {
            this.name = name;
            this.age = age;
            this.email = email;
        }
        // Getters are required by Gson for serialization
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getEmail() { return email; }
    }
}

访问 http://yourserver:port/yourApp/jsonResponse,浏览器会显示:

{"name":"张三","age":30,"email":"zhangsan@example.com"}

示例 3:返回不同状态码(如 404, 500)

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/statusResponse")
public class StatusResponseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String type = request.getParameter("type");
        if ("notfound".equals(type)) {
            // 返回 404 Not Found 状态码
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "请求的资源不存在");
        } else if ("servererror".equals(type)) {
            // 返回 500 Internal Server Error 状态码
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器内部错误");
        } else {
            // 返回 200 OK 状态码(默认)
            response.setContentType("text/plain");
            response.getWriter().write("请求成功,状态码为 200");
        }
    }
}

Spring Boot 方式

Spring Boot 极大地简化了返回响应的过程,你不需要手动操作 HttpServletResponse,也不需要手动引入 JSON 转换库(Spring Boot 默认会为你配置好 Jackson)。

Spring Boot 会根据你的返回值类型、注解和配置,自动帮你完成所有事情。

Java如何构建标准HTTP响应?-图3
(图片来源网络,侵删)

示例 1:返回纯文本

直接在 Controller 方法中返回一个字符串即可。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // @RestController = @Controller + @ResponseBody
public class TextResponseController {
    @GetMapping("/text")
    public String getTextResponse() {
        return "这是一个来自 Spring Boot 的纯文本响应!";
    }
}
  • @RestController:这个注解告诉 Spring,这个类中的所有方法返回的都是响应体(Response Body),而不是一个视图名称。
  • Spring 会自动将返回的字符串通过 StringHttpMessageConverter 写入 HTTP 响应。

示例 2:返回 JSON 数据(最佳实践)

这是 Spring Boot 的精髓所在,你只需要返回一个 Java 对象,Spring Boot 会自动将其序列化为 JSON。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class JsonResponseController {
    @GetMapping("/user")
    public User getUserResponse() {
        // Spring Boot 会自动调用 Jackson (默认) 或 Gson 将这个对象转为 JSON
        return new User("李四", 28, "lisi@example.com");
    }
    // POJO (Plain Old Java Object) - 一个简单的 Java 对象
    // Spring Boot 会自动序列化这个对象
    static class User {
        private String name;
        private int age;
        private String email;
        public User(String name, int age, String email) {
            this.name = name;
            this.age = age;
            this.email = email;
        }
        // Getters and Setters are required by Jackson for serialization/deserialization
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public int getAge() { return age; }
        public void setAge(int age) { this.age = age; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
    }
}

访问 http://yourserver:port/yourApp/user,浏览器会显示:

{"name":"李四","age":28,"email":"lisi@example.com"}

注意:必须提供 getter/setter 或将属性设为 public,Jackson 才能正确序列化/反序列化。


示例 3:返回自定义响应结构(统一格式)

在实际项目中,我们通常希望所有 API 的返回格式是统一的,

{
  "code": 200,
  "message": "success",
  "data": { ... }
}

Spring Boot 可以轻松实现这一点,推荐使用 record (Java 14+) 或一个简单的 POJO 来表示响应体。

使用 record (简洁推荐)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
// 定义一个通用的响应记录
record ApiResponse<T>(int code, String message, T data) {}
@RestController
public class UnifiedResponseController {
    @GetMapping("/unified-user")
    public ApiResponse<User> getUnifiedResponse() {
        User user = new User("王五", 35, "wangwu@example.com");
        // 直接返回这个统一的响应结构
        return new ApiResponse<>(200, "查询成功", user);
    }
    // User 类同上,省略...
}

使用自定义 POJO 类(兼容性更好)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
// 自定义统一响应类
class StandardResponse<T> {
    private int code;
    private String message;
    private T data;
    // 构造函数、Getters and Setters...
    public StandardResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    // Getters and Setters are required by Jackson
    public int getCode() { return code; }
    public String getMessage() { return message; }
    public T getData() { return data; }
}
@RestController
public class UnifiedResponseControllerV2 {
    @GetMapping("/unified-user-v2")
    public StandardResponse<User> getUnifiedResponseV2() {
        User user = new User("赵六", 40, "zhaoliu@example.com");
        return new StandardResponse<>(200, "操作成功", user);
    }
    // User 类同上,省略...
}

示例 4:设置状态码和响应头

Spring Boot 提供了 ResponseEntity 类,让你可以完全控制 HTTP 响应的各个方面。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ResponseEntityController {
    @GetMapping("/entity")
    public ResponseEntity<String> getEntityResponse() {
        // 设置响应体
        String body = "这是一个使用 ResponseEntity 构建的响应";
        // 设置自定义响应头
        // response.setHeader("Custom-Header", "MyValue");
        // 返回一个包含状态码、响应头和响应体的 ResponseEntity 对象
        return ResponseEntity
                .status(HttpStatus.CREATED) // 设置状态码为 201
                .header("X-Custom-Header", "some-value") // 设置自定义响应头
                .body(body);
    }
    @GetMapping("/not-found")
    public ResponseEntity<String> getNotFoundResponse() {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("资源未找到");
    }
}

总结对比

特性 Servlet 原生 API Spring Boot
核心对象 HttpServletResponse Controller 方法的返回值 / ResponseEntity
返回 JSON 手动引入库 (Gson/Jackson),手动转换对象为字符串,再写入流。 自动完成,返回 Java 对象,Spring Boot 自动用 Jackson 序列化为 JSON。
统一响应格式 需要手动创建一个包装类,并在每个方法中手动构造 JSON 字符串。 非常方便,可以定义一个通用的 record 或 POJO,直接返回它即可。
设置状态码/头 调用 response.setStatus(), response.setHeader() 使用 ResponseEntity.status(), .header() 进行精细控制。
简洁性 繁琐,需要处理很多底层细节。 非常简洁,专注于业务逻辑,框架处理所有技术细节。
推荐场景 学习 Servlet 原理、维护老旧项目。 所有现代 Java Web 项目开发,尤其是微服务。

对于任何新的 Java Web 项目,强烈推荐使用 Spring Boot,它通过约定优于配置和自动化的方式,让你能以最少的代码、最清晰的结构完成复杂的响应构建工作,而理解 Servlet 原理则有助于你更好地排查问题和理解底层机制。

分享:
扫描分享到社交APP
上一篇
下一篇