@JSONProperty注解详解
什么是@JSONProperty注解
@JSONProperty是Jackson库提供的一个注解,用于控制Java对象属性在JSON序列化和反序列化过程中的行为。它允许我们自定义JSON字段名、访问顺序、是否包含某个字段等。
基本用法
1. 修改JSON字段名
public class User {
@JSONProperty("user_name")
private String name;
@JSONProperty("user_age")
private Integer age;
// getter和setter方法
}
这样,当将User对象转换为JSON时,属性名将变为user_name和user_age,而不是默认的驼峰命名。
2. 设置属性顺序
public class Order {
@JSONProperty(ordinal = 1)
private String orderId;
@JSONProperty(ordinal = 3)
private BigDecimal amount;
@JSONProperty(ordinal = 2)
private Date createTime;
// getter和setter方法
}
通过ordinal属性可以控制JSON输出中字段的顺序。
3. 条件性包含属性
public class Product {
private String id;
@JSONProperty(includeIfNull = false)
private String description;
@JSONProperty(serialze = false)
private String internalCode;
// getter和setter方法
}
includeIfNull = false:当属性值为null时不包含在JSON中serialze = false:禁止序列化该属性
在Spring Boot开发MCP中的实际应用
在Spring Boot项目中,特别是开发微服务(Microservices)或API网关时,经常需要处理不同系统间的数据格式转换问题。@JSONProperty注解可以帮助我们解决以下常见问题:
1. 统一API响应格式
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user.toResponse());
}
}
// DTO类
public class UserResponse {
@JSONProperty("userId")
private Long id;
@JSONProperty("fullName")
private String name;
@JSONProperty("emailAddress")
private String email;
@JSONProperty("registrationDate")
private LocalDateTime registerDate;
// 构造函数、getter和setter方法
public static UserResponse from(User user) {
UserResponse response = new UserResponse();
response.id = user.getId();
response.name = user.getName();
response.email = user.getEmail();
response.registerDate = user.getCreatedAt();
return response;
}
}
2. 处理数据库字段名与API字段名的不一致
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_name")
private String name;
@Column(name = "user_email")
private String email;
@Column(name = "create_time")
private LocalDateTime createdAt;
// getter和setter方法
}
// 使用@JSONProperty保持一致性
public class UserDTO {
@JSONProperty("userId")
private Long id;
@JSONProperty("name")
private String name;
@JSONProperty("email")
private String email;
@JSONProperty("createdAt")
private LocalDateTime createdAt;
// 构造函数、getter和setter方法
}
3. 敏感信息过滤
public class UserProfile {
private String id;
private String username;
@JSONProperty(serialze = false)
private String password;
@JSONProperty(serialze = false)
private String securityQuestion;
@JSONProperty(serialze = false)
private String securityAnswer;
// getter和setter方法
}
高级用法
1. 自定义命名策略
public class CustomNamingStrategy implements NamingStrategy {
@Override
public String translate(String input) {
// 实现自定义命名规则,如全部大写、添加前缀等
return "PREFIX_" + input.toUpperCase();
}
@Override
public String getClassName(String input, boolean lowerCase) {
return translate(input);
}
@Override
public String[] split(String input) {
// 实现字符串分割逻辑
return input.split("_");
}
}
// 配置Jackson使用自定义命名策略
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new CustomNamingStrategy());
return mapper;
}
}
2. 条件性序列化
public class ConditionalUser {
private String id;
private String name;
@JSONProperty(serialzeUsing = SerializationFeature.class)
private String role;
@JSONProperty(deserialzeUsing = DeserializationFeature.class)
private String permissions;
// getter和setter方法
}
3. 多态序列化
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Car.class, name = "car"),
@JsonSubTypes.Type(value = Bike.class, name = "bike")
})
public abstract class Vehicle {
private String brand;
@JSONProperty("vehicleBrand")
public String getBrand() {
return brand;
}
}
public class Car extends Vehicle {
private int numberOfDoors;
@JSONProperty("doors")
public int getNumberOfDoors() {
return numberOfDoors;
}
}
public class Bike extends Vehicle {
private boolean hasBasket;
@JSONProperty("hasStorage")
public boolean isHasBasket() {
return hasBasket;
}
}
总结
@JSONProperty注解为Spring Boot应用中的JSON处理提供了极大的灵活性。通过使用这个注解,我们可以:
- 统一API接口的数据格式,提高一致性
- 隐藏内部实现细节,只暴露必要的字段
- 处理数据库字段名与API字段名的差异
- 控制JSON输出的顺序
- 实现条件性序列化和反序列化
在实际开发中,合理使用@JSONProperty注解能够显著提升代码的可维护性和API的专业度。特别是在微服务架构中,不同服务间的数据格式标准化变得尤为重要,@JSONProperty注解成为了不可或缺的利器。