



在Spring Boot中,返回JSON数据非常简单,spring-boot-starter-web依赖自带了Jackson库,它可以自动将Java对象序列化为JSON格式。
Jackson支持将各种Java对象序列化为JSON,包括列表(List)、映射(Map)、集合(Set)、基本数据类型及其包装类等。
当使用@RestController注解时,Spring Boot会自动使用Jackson库来完成这些对象的序列化。例如,基于2.2.2节创建的Book类,在控制器中返回数据信息,代码如下。
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
// 实际应用中,可能会返回从数据库中查询的数据
return new Book("The Great Gatsby", "F. Scott Fitzgerald");
}
}
需要修改Book类,为其添加构造器,代码如下。
public Book(String title, String author) {
this.title = title;
this.author = author;
}
当访问/books/1(或任何ID)时,会得到以下JSON响应。
{
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald"
}
上述只是返回JSON数据的基本示例。实际应用中,可能还需要处理更复杂的数据结构,如错误处理、HTTP状态码等,为了保持API的一致性和可读性,许多项目都会封装一个公共的结果类来标准化响应的结构。这样,不管请求是成功还是失败,返回给客户端的格式都是一致的。这种模式不仅使前端开发更简单,还使后端代码更具组织性。
以下是一个简单的公共结果类示例。
public class ApiResponse<T> {
private boolean success; // 请求是否成功
private String message; // 错误消息
private T data; // 返回的数据
private int code; // 自定义状态码
// 省略构造函数、Getter和Setter方法
// 成功时的静态工厂方法
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setSuccess(true);
response.setData(data);
response.setCode(20000); // 自定义成功码
return response;
}
// 失败时的静态工厂方法
public static <T> ApiResponse<T> error(String message, int errorCode) {
ApiResponse<T> response = new ApiResponse<>();
response.setSuccess(false);
response.setMessage(message);
response.setCode(errorCode); // 自定义错误码
return response;
}
}
ApiResponse<T>是一个用于Spring Boot应用程序的通用响应结果类,旨在标准化API响应。该类使用Java泛型,允许不同类型的数据作为响应返回,如String、List<Book>或其他自定义对象。
ApiResponse<T>的成员变量用于封装数据及表示请求成功或失败的信息。
success:布尔值,表示API请求是否成功。通常成功执行的业务逻辑设置为true,否则为false。
message:存储请求失败时的错误消息,如“资源未找到”等。
data:泛型字段,用于存储请求成功时返回的数据。
code:整数值,表示自定义的状态码。例如,可以用20000表示成功的状态,其他数字表示不同类型的错误或状态。
类中提供了两个静态工厂方法用于创建ApiResponse对象,其中:
success(T data):用于创建表示成功响应的对象。设置success为true,并将数据设置为data字段。
error(String message, int errorCode):创建表示失败响应的对象。设置success为false,message字段为错误消息,code为传入的自定义错误码。
在控制器中,使用ApiResponse<T>类可以返回结构化的响应,包括成功和失败的场景,代码如下。
@RestController
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping("/{id}")
public ApiResponse<Book> getBookById(@PathVariable Long id) {
// 假设查找书籍,这里只是模拟
Book book = findBookById(id);
if (book != null) {
return ApiResponse.success(book);
} else {
return ApiResponse.error("Book not found", 40000); // 使用自定义
错误码
}
}
}
对于成功的请求,响应可能是:
{
"success": true,
"data": {
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald"
},
"code": 20000
}
对于失败的请求,响应可能是:
{
"success": false,
"message": "Book not found",
"code": 40000
}
通过这种方式,ApiResponse<T>类不仅提供了操作结果的信息(成功或失败),还通过code字段提供了更具体的状态描述,使得API的使用者能够更清晰地理解响应的含义。
需要注意的是,在上述案例中,无论请求成功还是失败,HTTP状态码始终保持为200。这意味着从HTTP的角度看,所有请求都被视为成功。
然而,具体的业务逻辑结果是通过自定义状态码传达的。此种方式可以减少由于不同HTTP状态码引起的潜在混淆,特别是在复杂的应用程序中,其中业务逻辑可能比HTTP协议提供的状态更为复杂。