Spring Boot 返回 JSON 数据配置全攻略**
在现代 Web 开发中,JSON(JavaScript Object Notation)已成为前后端数据交换的主流格式,Spring Boot 框架对 JSON 提供了卓越的支持,使得开发者能够轻松地配置控制器以返回 JSON 数据,本文将详细介绍在 Spring Boot 中配置返回 JSON 的多种方式及相关细节。
默认配置:开箱即用的 JSON 支持
Spring Boot 的一个核心特性是“约定优于配置”,在大多数情况下,当你创建一个 Spring Boot 项目并引入了 Web 依赖后,它已经默认为你配置好了 JSON 的序列化与反序列化。
-
引入必要依赖: 你只需要在
pom.xml(Maven) 或build.gradle(Gradle) 中引入spring-boot-starter-web依赖,它会自动引入 Jackson 库(jackson-databind,jackson-core,jackson-annotations),这是 Spring Boot 默认的 JSON 处理库。<!-- pom.xml --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> -
创建返回 POJO 的控制器: 你只需要创建一个 Spring MVC 控制器,并在处理方法中返回一个普通 Java 对象(POJO)或集合(如
List,Map),Spring Boot 会自动使用 Jackson 库将该对象序列化为 JSON 字符串,并设置正确的Content-Type为application/json。示例:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/user") public User getUser() { User user = new User(); user.setId(1L); user.setName("张三"); user.setEmail("zhangsan@example.com"); return user; } @GetMapping("/users") public List<User> getUsers() { // 假设已经有一些 User 对象 return List.of( new User(1L, "张三", "zhangsan@example.com"), new User(2L, "李四", "lisi@example.com") ); } } // User 实体类 class User { private Long id; private String name; private String email; // 构造方法、getter 和 setter public User() {} public User(Long id, String name, String email) { this.id = id; this.name = name; this.email = email; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }访问
/user会返回类似{"id":1,"name":"张三","email":"zhangsan@example.com"}的 JSON。 访问/users会返回 JSON 数组。
手动配置 Jackson
虽然默认配置足够应对大多数场景,但有时我们需要对 Jackson 的行为进行自定义,例如日期格式、字段命名策略、忽略某些字段等,Spring Boot 提供了多种方式来配置 Jackson。
-
通过
application.properties或application.yml配置: 这是最简单的方式,无需编写额外代码,Spring Boot 会自动将这些属性绑定到 Jackson 的ObjectMapper实例上。application.properties示例:# 日期格式化 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss # 时区设置 spring.jackson.time-zone=GMT+8 # 属性命名策略:SNAKE_CASE (如 user_name),默认是 CamelCase (如 userName) spring.jackson.property-naming-strategy=SNAKE_CASE # 是否忽略未知属性(反序列化时遇到目标类没有的属性是否报错) spring.jackson.deserialization.fail-on-unknown-properties=false # 是否忽略空属性(序列化时是否忽略值为 null 的属性) spring.jackson.default-property-inclusion=NON_NULL
application.yml示例:spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 property-naming-strategy: SNAKE_CASE deserialization: fail-on-unknown-properties: false default-property-inclusion: non_null -
通过 Java 配置类自定义
ObjectMapper: 当需要更复杂的配置,或者希望将 Jackson 配置与其他 Spring 配置集中管理时,可以创建一个配置类并实现Jackson2ObjectMapperBuilderCustomizer接口,或者直接配置ObjectMapperBean。示例:实现
Jackson2ObjectMapperBuilderCustomizer:import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jackson.databind.SerializationFeature; import org.springframework.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Configuration public class JacksonConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return jacksonObjectMapperBuilder -> { // 日期时间格式化 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); jacksonObjectMapperBuilder .serializers(new LocalDateTimeSerializer(dateTimeFormatter)) .propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) .modules(new JavaTimeModule()); // 处理 Java 8 时间类型 // 禁用将日期序列为时间戳 jacksonObjectMapperBuilder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); }; } // 或者直接配置 ObjectMapper Bean @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 自定义配置 objectMapper.registerModule(new JavaTimeModule()); objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); return objectMapper; } }注意:如果你直接提供了
ObjectMapperBean,Spring Boot 可能不会自动应用默认的 Jackson 配置,所以需要确保你的配置足够全面,使用Jackson2ObjectMapperBuilderCustomizer通常更推荐,因为它是在默认配置基础上进行定制。
使用 @ResponseBody 注解
在 Spring MVC 中,@ResponseBody 注解可以放在方法或类上,表示方法的返回值直接写入 HTTP 响应体中,而不是解析为视图名称,结合 @RestController(它本身就是 @Controller + @ResponseBody 的组合),我们可以非常方便地返回 JSON。
-
在方法上使用
@ResponseBody: 如果控制器类使用了@Controller而不是@RestController,那么需要在返回 JSON 的方法上添加@ResponseBody注解。import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class JsonController { @GetMapping("/data") @ResponseBody public String getData() { return "{\"message\":\"Hello from @ResponseBody\"}"; } } -
在类上使用
@RestController: 如前所述,@RestController已经隐式地包含了@ResponseBody,所以该控制器下的所有方法都会返回 JSON 或其他直接写入响应体的数据。
使用 @JsonView 注解进行选择性序列化
有时,我们希望同一个对象在不同场景下返回不同的 JSON 字段,Spring 提供了 @JsonView 注解来实现这一功能。
-
定义视图标记接口:
public class Views { public interface Public {} public interface Internal extends Public {} } -
在实体类上指定视图:
import com.fasterxml.jackson.annotation.JsonView; public class User { @JsonView(Views.Public.class) private Long id; @JsonView(Views.Public.class) private String name; @JsonView(Views.Internal.class) private String email; // 构造方法、getter 和 setter // ... } -
在控制器方法上指定视图:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/user/public") @JsonView(Views.Public.class) public User getPublicUser() { // 返回 User 对象



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