Jackson 是一个高性能的 JSON 处理库,广泛用于 Java 应用程序中进行 JSON 的序列化和反序列化。以下是 Jackson 序列化的主要方式和一些关键概念的介绍。

1. 基本序列化

1.1 添加依赖

首先,在你的 pom.xml 文件中添加 Jackson 的依赖:

<dependencies>
    <!-- Jackson Core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.15.2</version>
    </dependency>
    <!-- Jackson Databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
    <!-- Jackson Annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.15.2</version>
    </dependency>
</dependencies>

1.2 创建对象

假设你有一个简单的 Java 类 User

import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private String name;
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @JsonProperty("full_name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

1.3 序列化对象

使用 ObjectMapper 将 Java 对象序列化为 JSON 字符串:

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            User user = new User("John Doe", 30);
            String jsonString = objectMapper.writeValueAsString(user);
            System.out.println(jsonString);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:

{"full_name":"John Doe","age":30}

2. 注解配置

Jackson 提供了多种注解来控制序列化和反序列化的行为。

2.1 @JsonProperty

指定字段在 JSON 中的名称。

@JsonProperty("full_name")
public String getName() {
    return name;
}

2.2 @JsonIgnore

忽略某个字段,使其不被序列化或反序列化。

@JsonIgnore
private String sensitiveData;

2.3 @JsonInclude

控制哪些字段会被包含在序列化的 JSON 中。

@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
    private String name;
    private Integer age; // 使用包装类型,null 值不会被序列化
}

2.4 @JsonFormat

格式化日期和时间。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Event {
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date eventDate;

    // Getters and setters
}

3. 自定义序列化器

有时你需要更复杂的序列化逻辑,这时可以实现自定义的序列化器。

3.1 创建自定义序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CustomDateSerializer extends StdSerializer<Date> {

    private static final SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");

    public CustomDateSerializer() {
        this(null);
    }

    public CustomDateSerializer(Class<Date> t) {
        super(t);
    }

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        String formattedDate = formatter.format(value);
        gen.writeString(formattedDate);
    }
}

3.2 使用自定义序列化器

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class Event {
    private String name;

    @JsonSerialize(using = CustomDateSerializer.class)
    private Date eventDate;

    // Getters and setters
}

4. 深度定制

4.1 Module

你可以创建自定义的 Module 来注册自定义的序列化器和反序列化器。

import com.fasterxml.jackson.databind.module.SimpleModule;

public class CustomModule extends SimpleModule {
    public CustomModule() {
        super("CustomModule");
        addSerializer(Date.class, new CustomDateSerializer());
    }
}

4.2 注册 Module

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new CustomModule());

5. 示例

以下是一个完整的示例,展示了如何使用 Jackson 进行序列化和反序列化,并使用自定义注解和序列化器。

5.1 定义类

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.util.Date;

public class User {
    @JsonProperty("full_name")
    private String name;

    private int age;

    @JsonIgnore
    private String sensitiveData;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date registrationDate;

    @JsonSerialize(using = CustomDateSerializer.class)
    private Date lastLoginDate;

    public User() {}

    public User(String name, int age, String sensitiveData, Date registrationDate, Date lastLoginDate) {
        this.name = name;
        this.age = age;
        this.sensitiveData = sensitiveData;
        this.registrationDate = registrationDate;
        this.lastLoginDate = lastLoginDate;
    }

    // Getters and setters
}

5.2 主类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.util.Date;

public class Main {
    public static void main(String[] args) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addSerializer(Date.class, new CustomDateSerializer());
            objectMapper.registerModule(module);

            User user = new User(
                "John Doe",
                30,
                "Sensitive Info",
                new Date(),
                new Date()
            );

            String jsonString = objectMapper.writeValueAsString(user);
            System.out.println(jsonString);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出示例:

{"full_name":"John Doe","age":30,"registrationDate":"2023-10-05","lastLoginDate":"05-10-2023"}

总结

Jackson 提供了灵活且强大的机制来进行 JSON 的序列化和反序列化。通过使用注解、自定义序列化器和模块,你可以精确控制 JSON 的生成方式,以满足各种复杂的需求。