Jackson库提供了多种注解(annotations),可以用来控制JSON序列化和反序列化的行为。这些注解允许你灵活地映射Java对象与JSON数据之间的关系。下面将详细介绍一些常用的Jackson注解及其用法。
1. @JsonProperty
作用: 用于指定JSON属性与Java类字段的映射关系。可以用来重命名字段,或指定序列化/反序列化时的字段名。
示例:
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
@JsonProperty("user_name")
private String name;
@JsonProperty("user_age")
private int age;
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonPropertyExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建User对象
User user = new User();
user.setName("John Doe");
user.setAge(30);
// 序列化为JSON
String jsonString = mapper.writeValueAsString(user);
System.out.println(jsonString); // 输出: {"user_name":"John Doe","user_age":30}
// 反序列化JSON
User deserializedUser = mapper.readValue(jsonString, User.class);
System.out.println(deserializedUser); // 输出: User{name='John Doe', age=30}
}
}
2. @JsonIgnore
作用: 用于忽略某个字段,避免将其序列化到JSON中或从JSON中反序列化该字段。
示例:
import com.fasterxml.jackson.annotation.JsonIgnore;
public class User {
private String name;
private int age;
@JsonIgnore
private String password;
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonIgnoreExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建User对象
User user = new User();
user.setName("John Doe");
user.setAge(30);
user.setPassword("secret");
// 序列化为JSON
String jsonString = mapper.writeValueAsString(user);
System.out.println(jsonString); // 输出: {"name":"John Doe","age":30}
}
}
3. @JsonInclude
作用: 用于指定序列化时应包括哪些字段。例如,可以设置为JsonInclude.Include.NON_NULL
,仅包括非空字段。
示例:
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
private Integer age; // 使用包装类以允许null值
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonIncludeExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建User对象
User user = new User();
user.setName("John Doe");
// age字段没有设置值,因此在序列化时将被忽略
// 序列化为JSON
String jsonString = mapper.writeValueAsString(user);
System.out.println(jsonString); // 输出: {"name":"John Doe"}
}
}
4. @JsonFormat
作用: 用于指定日期和时间字段的格式化方式。例如,可以指定日期格式。
示例:
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class Event {
private String title;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date eventDate;
// Getter和Setter方法
@Override
public String toString() {
return "Event{" +
"title='" + title + '\'' +
", eventDate=" + eventDate +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.text.SimpleDateFormat;
import java.util.Date;
public class JsonFormatExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
// 创建Event对象
Event event = new Event();
event.setTitle("Annual Meeting");
event.setEventDate(new Date());
// 序列化为JSON
String jsonString = mapper.writeValueAsString(event);
System.out.println(jsonString); // 输出: {"title":"Annual Meeting","eventDate":"2024-07-25"}
}
}
5. @JsonCreator
和 @JsonProperty
作用: @JsonCreator
用于标记构造函数或工厂方法,使Jackson在反序列化时使用这个构造函数或方法。@JsonProperty
用于指定构造函数参数的名称。
示例:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
private String name;
private int age;
@JsonCreator
public User(@JsonProperty("name") String name, @JsonProperty("age") int age) {
this.name = name;
this.age = age;
}
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonCreatorExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// JSON字符串
String jsonString = "{\"name\":\"John Doe\",\"age\":30}";
// 反序列化JSON
User user = mapper.readValue(jsonString, User.class);
System.out.println(user); // 输出: User{name='John Doe', age=30}
}
}
6. @JsonSetter
作用: 指定反序列化时应调用的方法。可以用来调整字段名的映射。
示例:
import com.fasterxml.jackson.annotation.JsonSetter;
public class User {
private String name;
private int age;
@JsonSetter("user_name")
public void setName(String name) {
this.name = name;
}
@JsonSetter("user_age")
public void setAge(int age) {
this.age = age;
}
// Getter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonSetterExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// JSON字符串
String jsonString = "{\"user_name\":\"John Doe\",\"user_age\":30}";
// 反序列化JSON
User user = mapper.readValue(jsonString, User.class);
System.out.println(user); // 输出: User{name='John Doe', age=30}
}
}
7. @JsonDeserialize
和 @JsonSerialize
作用: 用于指定自定义的反序列化和序列化器。可以用来自定义字段的解析和序列化逻辑。
示例:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Event {
private String title;
@JsonSerialize(using = CustomDateSerializer.class)
@JsonDeserialize(using = CustomDateDeserializer.class)
private Date eventDate;
// Getter和Setter方法
public static class CustomDateSerializer extends JsonSerializer<Date> {
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public void serialize(Date date, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(dateFormat.format(date));
}
}
public static class CustomDateDeserializer extends JsonDeserializer<Date> {
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
try {
return dateFormat.parse(p.getText());
} catch (ParseException e) {
throw new IOException(e);
}
}
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.text.SimpleDateFormat;
import java.util.Date;
public class JsonSerializeDeserializeExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
// 创建Event对象
Event event = new Event();
event.setTitle("Annual Meeting");
event.setEventDate(new Date());
// 序列化为JSON
String jsonString = mapper.writeValueAsString(event);
System.out.println(jsonString); // 输出: {"title":"Annual Meeting","eventDate":"2024-07-25"}
// 反序列化JSON
Event deserializedEvent = mapper.readValue(jsonString, Event.class);
System.out.println(deserializedEvent); // 输出: Event{title='Annual Meeting', eventDate=Tue Jul 25 00:00:00 UTC 2024}
}
}
8. @JsonManagedReference
和 @JsonBackReference
作用: 用于处理双向关系中的循环引用问题。@JsonManagedReference
用于标记父对象中的字段,@JsonBackReference
用于标记子对象中的字段。
示例:
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
public class User {
private String name;
@JsonManagedReference
private Address address;
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", address=" + address +
'}';
}
}
public class Address {
private String street;
@JsonBackReference
private User user;
// Getter和Setter方法
@Override
public String toString() {
return "Address{" +
"street='" + street + '\'' +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonManagedBackReferenceExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建User和Address对象
User user = new User();
user.setName("John Doe");
Address address = new Address();
address.setStreet("123 Main St");
address.setUser(user);
user.setAddress(address);
// 序列化为JSON
String jsonString = mapper.writeValueAsString(user);
System.out.println(jsonString); // 输出: {"name":"John Doe","address":{"street":"123 Main St"}}
// 反序列化JSON
User deserializedUser = mapper.readValue(jsonString, User.class);
System.out.println(deserializedUser); // 输出: User{name='John Doe', address=Address{street='123 Main St'}}
}
}
9. @JsonAlias
作用: 允许字段有多个别名,以便在反序列化时接受不同名称的JSON属性。
示例:
import com.fasterxml.jackson.annotation.JsonAlias;
public class User {
@JsonAlias({"username", "user_name"})
private String name;
@JsonAlias({"userage", "user_age"})
private int age;
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonAliasExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// JSON字符串
String jsonString = "{\"username\":\"John Doe\",\"userage\":30}";
// 反序列化JSON
User user = mapper.readValue(jsonString, User.class);
System.out.println(user); // 输出: User{name='John Doe', age=30}
}
}
10. @JsonUnwrapped
作用: 将嵌套对象的属性“展开”到父对象中。这在处理嵌套结构时特别有用。
示例:
import com.fasterxml.jackson.annotation.JsonUnwrapped;
public class User {
private String name;
private int age;
@JsonUnwrapped
private Address address;
// Getter和Setter方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
public class Address {
private String street;
private String city;
// Getter和Setter方法
@Override
public String toString() {
return "Address{" +
"street='" + street + '\'' +
", city='" + city + '\'' +
'}';
}
}
用法:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonUnwrappedExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建User和Address对象
User user = new User();
user.setName("John Doe");
user.setAge(30);
Address address = new Address();
address.setStreet("123 Main St");
address.setCity("Springfield");
user.setAddress(address);
// 序列化为JSON
String jsonString = mapper.writeValueAsString(user);
System.out.println(jsonString); // 输出: {"name":"John Doe","age":30,"street":"123 Main St","city":"Springfield"}
// 反序列化JSON
User deserializedUser = mapper.readValue(jsonString, User.class);
System.out.println(deserializedUser); // 输出: User{name='John Doe', age=30, address=Address{street='123 Main St', city='Springfield'}}
}
}
总结
Jackson库中的注解可以帮助你灵活地控制JSON数据的序列化和反序列化过程。通过合理使用这些注解,你可以实现字段重命名、忽略字段、设置字段包含策略、处理日期格式、定义自定义序列化和反序列化逻辑、解决循环引用问题、多态处理等功能。这些功能使得Jackson在处理复杂JSON数据时非常强大和灵活。