SpringBoot 如何实现 JSON 返回页面?详解与实践指南
在 SpringBoot 开发中,我们经常需要根据不同的业务场景返回不同格式的数据,JSON 是前后端分离架构中最常用的数据交互格式,本文将详细介绍如何在 SpringBoot 中实现 JSON 数据的返回,包括基础配置、常用注解、自定义响应格式以及高级技巧,帮助你灵活应对各种开发需求。
基础配置:启用 JSON 支持
SpringBoot 默认已经内置了 Jackson 和 Gson 等 JSON 处理库,开箱即用,要实现 JSON 返回,我们只需要确保项目依赖正确即可。
检查依赖
在 pom.xml 中,确保有以下依赖(SpringBoot Web 依赖通常会自动包含 Jackson):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
默认 JSON 配置
SpringBoot 会自动配置 ObjectMapper,这是 Jackson 的核心类,用于 Java 对象与 JSON 的转换,你可以通过 application.properties 或 application.yml 进行基本配置:
# application.properties spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8 spring.jackson.default-property-inclusion=non_null
实现 JSON 返回的常用方式
使用 @ResponseBody 注解
在控制器方法上添加 @ResponseBody 注解,Spring 会自动将返回的对象序列化为 JSON 格式。
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/user/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
User user = userService.findById(id);
return user;
}
}
注意:当类上使用 @RestController 时,默认所有方法都带有 @ResponseBody,无需单独添加。
使用 ResponseEntity 封装响应
ResponseEntity 允许你更灵活地控制响应状态码、头部和体内容。
@GetMapping("/user/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
if (user != null) {
return ResponseEntity.ok(user);
} else {
return ResponseEntity.notFound().build();
}
}
统一响应格式
为了保持 API 的一致性,我们可以定义一个统一的响应格式:
public class ApiResponse<T> {
private int code;
private String message;
private T data;
// 构造方法、getter 和 setter
}
然后在控制器中使用:
@GetMapping("/user/{id}")
public ApiResponse<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return new ApiResponse<>(200, "success", user);
}
高级配置与技巧
自定义 ObjectMapper
如果需要更复杂的 JSON 序列化配置,可以自定义 ObjectMapper:
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// 其他配置...
return mapper;
}
}
处理循环引用
在实体类关系中,可能会出现循环引用导致 JSON 序列化失败,可以使用 @JsonIgnore 注解或配置 ObjectMapper:
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.addHandler(new SimpleModule().addSerializer(Object.class, new JsonSerializer<Object>() {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeObject(value);
}
}));
return mapper;
}
}
使用 @JsonView 控制序列化字段
可以根据不同的视图需求序列化不同的字段:
public class Views {
public interface Public {}
public interface Internal extends Public {}
}
public class User {
@JsonView(Views.Public.class)
private String username;
@JsonView(Views.Internal.class)
private String password;
// 其他字段和方法
}
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/user/{id}")
@JsonView(Views.Public.class)
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@GetMapping("/admin/user/{id}")
@JsonView(Views.Internal.class)
public User getAdminUser(@PathVariable Long id) {
return userService.findById(id);
}
}
异常处理与 JSON 错误响应
使用 @ControllerAdvice 和 @ExceptionHandler 统一处理异常并返回 JSON 格式错误信息:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public ApiResponse<String> handleException(Exception e) {
return new ApiResponse<>(500, e.getMessage(), null);
}
@ExceptionHandler(UserNotFoundException.class)
@ResponseBody
public ApiResponse<String> handleUserNotFound(UserNotFoundException e) {
return new ApiResponse<>(404, e.getMessage(), null);
}
}
完整示例
下面是一个完整的示例,展示如何实现一个带有统一响应格式的 JSON API:
定义统一响应类
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public ApiResponse(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
// 省略 getter 和 setter
}
定义用户实体类
public class User {
private Long id;
private String username;
private String email;
// 省略 getter 和 setter
}
实现控制器
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ApiResponse<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
if (user != null) {
return new ApiResponse<>(200, "success", user);
} else {
return new ApiResponse<>(404, "User not found", null);
}
}
@PostMapping
public ApiResponse<User> createUser(@RequestBody User user) {
User createdUser = userService.save(user);
return new ApiResponse<>(201, "User created", createdUser);
}
}
自定义配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
converter.setObjectMapper(mapper);
converters.add(converter);
}
}
在 SpringBoot 中实现 JSON 返回非常简单,主要通过以下几种方式:
- 使用
@RestController或@ResponseBody注解 - 使用
ResponseEntity控制响应细节 - 定义统一的响应格式保持 API 一致性
- 通过配置
ObjectMapper满足复杂的序列化需求 - 使用
@ControllerAdvice统一处理异常
通过合理运用这些技术,你可以构建出既规范又灵活的 JSON API,满足各种前后端分离场景的需求,良好的 API 设计不仅要考虑功能的实现,还要注重用户体验和可维护性。



还没有评论,来说两句吧...