【Jackson】注解及其使用

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数据时非常强大和灵活。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值