java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Jackson ObjectMapper用法

Java Jackson之ObjectMapper常用用法总结

作者:洪宏鸿

这篇文章主要给大家介绍了关于Java Jackson之ObjectMapper常用用法的相关资料,ObjectMapper是一个Java库,用于将JSON字符串转换为Java对象或将Java对象转换为JSON字符串,需要的朋友可以参考下

ObjectMapper的使用

基本使用

ObjectMapper 是 Jackson 序列化和反序列化 JSON 和 Java 对象的核心类,提供了许多用于定制序列化和反序列化的方法和配置选项。

以下是 ObjectMapper 的基本使用示例:

// 创建 ObjectMapper 对象
ObjectMapper objectMapper = new ObjectMapper();

// 将 Java 对象序列化为 JSON 字符串
String jsonString = objectMapper.writeValueAsString(obj);
// 创建 ObjectMapper 对象
ObjectMapper objectMapper = new ObjectMapper();

// 将 JSON 字符串反序列化为 Java 对象
MyClass myObj = objectMapper.readValue(jsonString, MyClass.class);

其中,writeValueAsString 方法用于将 Java 对象序列化为 JSON 字符串,readValue 方法用于将 JSON 字符串反序列化为 Java 对象。这里的 MyClass 表示需要反序列化成的 Java 对象类型。

在进行序列化和反序列化时,ObjectMapper 会自动根据 Java 对象的属性和 JSON 的键值对进行映射,进行相应的转换。例如,Java 对象的属性名为 propertyName,JSON 中的键名为 keyName,则 ObjectMapper 会自动将它们进行对应,将 propertyName 的值序列化为 keyName 的值。

除了以上基本用法,ObjectMapper 还提供了很多其他的序列化和反序列化方法和配置选项,例如定制序列化规则、处理 JSON 中的日期格式、处理空值等等。

可以使用 Jackson 提供的注解来定制序列化规则,如 @JsonInclude、@JsonIgnore、@JsonProperty 等。也可以通过实现 JsonSerializer 接口来自定义序列化规则

可以使用 Jackson 提供的注解 @JsonFormat 来控制日期格式,也可以通过自定义序列化器来控制日期格式

可以使用 Jackson 提供的注解 @JsonInclude 来控制序列化时是否包含空值,也可以通过配置 ObjectMapper 来控制是否包含空值

其他用法

自定义序列化和反序列化

注解:可以在类或属性上添加注解来自定义序列化和反序列化的行为,例如@JsonSerialize和@JsonDeserialize。

public class Person {
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date birthday;
    @JsonDeserialize(using = CustomDateDeserializer.class)
    private Date registerTime;
    // getters and setters
}

public class CustomDateSerializer extends JsonSerializer<Date> {
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        gen.writeString(sdf.format(value));
    }
}

public class CustomDateDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = p.getText();
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new IOException("Failed to parse date: " + dateStr, e);
        }
    }
}

运行时动态地修改类的序列化和反序列化行为

Mixin:通过Mixin机制,可以在运行时动态地修改类的序列化和反序列化行为。

public class Person {
    private String name;
    private int age;
    // getters and setters
}

public interface PersonMixin {
    @JsonProperty("full_name")
    String getName();

    @JsonIgnore
    int getAge();
}

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(Person.class, PersonMixin.class);

多态序列化和反序列化

多态:使用@JsonTypeInfo和@JsonSubTypes注解,可以支持多态序列化和反序列化。

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"),
    @JsonSubTypes.Type(value = Circle.class, name = "circle")
})
public abstract class Shape {
    // ...
}

public class Rectangle extends Shape {
    // ...
}

public class Circle extends Shape {
    // ...
}

ObjectMapper objectMapper = new ObjectMapper();
Shape rectangle = new Rectangle();
Shape circle = new Circle();
String rectangleJson = objectMapper.writeValueAsString(rectangle);
String circleJson = objectMapper.writeValueAsString(circle);

转换

转换:使用ObjectMapper的convertValue方法,可以将一个对象转换为另一个类型的对象。

public class Person {
    private String name;
    private int age;
    // getters and setters
}

public class PersonDto {
    private String name;
    private int age;
    // getters and setters
}

ObjectMapper objectMapper = new ObjectMapper();
Person person = new Person("John", 20);
PersonDto personDto = objectMapper.convertValue(person, PersonDto.class);

序列化和反序列化选项

ObjectMapper提供了许多序列化和反序列化选项,可以通过ObjectMapper的各种方法进行配置。例如,可以通过configure方法设置SerializationFeature和DeserializationFeature等选项

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
String json = objectMapper.writeValueAsString(person);

以下是一些常用的属性配置及其作用:

除了上述常用的属性配置外,ObjectMapper 还提供了很多其他的配置选项,如时间格式化、空值处理、注解处理等,可以根据实际情况进行选择和定制化。

Jackson常用注解

Jackson 是一个用于序列化和反序列化 Java 对象与 JSON 数据的库,它提供了很多注解来定制序列化和反序列化的过程。以下是 Jackson 常用的注解及其作用:

这些注解可以在类、属性或者 getter/setter 方法上使用,以达到控制序列化和反序列化的效果。

@JsonProperty

这个注解用于将一个属性或方法序列化或反序列化为指定的名称。

例如,定义一个 Person 类:

public class Person {
    @JsonProperty("name")
    private String fullName;
    private int age;

    public Person(String fullName, int age) {
        this.fullName = fullName;
        this.age = age;
    }

    // getters and setters
}

在这个示例中,我们使用 @JsonProperty 注解将 fullName 属性序列化为 “name”,而不是默认的 “fullName”。

@JsonIgnore

这个注解用于忽略某个属性或方法,不进行序列化或反序列化。

例如,定义一个 Student 类:

public class Student {
    private String name;
    private int age;
    @JsonIgnore
    private String password;

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

    // getters and setters
}

在这个示例中,我们使用 @JsonIgnore 注解忽略 password 属性,不进行序列化或反序列化。

@JsonFormat

这个注解用于指定日期、时间等属性的序列化和反序列化格式。

例如,定义一个 Order 类:

public class Order {
    private String id;
    private Date createTime;

    public Order(String id, Date createTime) {
        this.id = id;
        this.createTime = createTime;
    }

    // getters and setters
}

在这个示例中,我们使用 @JsonFormat 注解指定 createTime 属性的序列化格式:

public class Order {
    private String id;
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    private Date createTime;

    public Order(String id, Date createTime) {
        this.id = id;
        this.createTime = createTime;
    }

    // getters and setters
}

在这个示例中,我们指定 createTime 属性的序列化格式为 “yyyy-MM-dd HH:mm:ss”,时区为 “GMT+8”

这个注解用于指定序列化时包含哪些属性,排除哪些属性。

例如,定义一个 Book 类:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Book {
    private String title;
    private String author;
    private String isbn;
    private Integer pages;

    public Book(String title, String author, String isbn, Integer pages) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
        this.pages = pages;
    }

    // getters and setters
}

在这个示例中,我们使用 @JsonInclude 注解指定序列化时只包含非空属性,排除为 null 的属性。这个示例中,序列化时只包含 title、author、isbn 这三个属性。

@JsonTypeInfo 和 @JsonSubTypes

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "animalType")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
    private String name;
    // getter and setter
}

public class Dog extends Animal {
    private String breed;
    // getter and setter
}

public class Cat extends Animal {
    private boolean hasClaws;
    // getter and setter
}

// 序列化
Animal dog = new Dog();
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(dog);
// 输出结果
{
  "name":null,
  "animalType":"dog",
  "breed":null
}

// 反序列化
String json = "{\"name\":\"Lucy\",\"animalType\":\"dog\",\"breed\":\"Golden Retriever\"}";
Animal animal = mapper.readValue(json, Animal.class);
// 输出结果
Dog{name='Lucy', breed='Golden Retriever'}

在上面的例子中,使用了 @JsonTypeInfo 和 @JsonSubTypes 注解实现了多态序列化和反序列化。@JsonTypeInfo 用来指定类型信息的序列化和反序列化方式,使用 JsonTypeInfo.Id.NAME 表示使用名称作为类型标识,并通过 property 属性指定类型标识的属性名。@JsonSubTypes 用来指定具体的子类型,使用 @JsonSubTypes.Type 注解指定子类型的类和类型标识。

@JsonAlias

@JsonAlias 注解可以指定多个属性名称作为别名

反序列化时被用来匹配。如果匹配到任意一个别名,则该别名对应的属性值就会被赋值给当前属性

需要注意的是,如果同时存在多个别名匹配到了同一个属性,序列化以最后一个匹配到的别名对应的值为准

public class Person {
    @JsonAlias({"name", "personName"})
    private String name;
    private int age;
    // getter and setter
}

// 序列化
Person person = new Person();
person.setName("Tom");
person.setAge(20);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// 输出结果
{"personName":"Tom","age":20}

// 反序列化
String json = "{\"name\":\"Lucy\",\"age\":18}";
Person person = mapper.readValue(json, Person.class);
// 输出结果
Person{name='Lucy', age=18}

在上面的例子中,使用了 @JsonAlias 注解来指定多个属性名的映射关系,用于序列化和反序列化。在序列化时,会使用注解中的任意一个属性名作为映射关系;在反序列化时,也会根据注解中的属性名进行映射

@JsonRawValue

@JsonRawValue注解表示一个属性值应该被直接写入JSON而不是被序列化为双引号中的字符串。它可以用于String属性或属性的getter方法上。使用这个注解需要注意安全问题,因为原始值不会被转义,可能会产生安全漏洞

假设有一个User类,其中有一个注解为@JsonRawValue的String类型属性。

public class User {
    private String name;
    @JsonRawValue
    private String info;

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

    public String getName() {
        return name;
    }

    public String getInfo() {
        return info;
    }
}

当我们序列化User对象时,info属性的值会直接被写入JSON中。

总结

到此这篇关于Java Jackson之ObjectMapper常用用法总结的文章就介绍到这了,更多相关Jackson ObjectMapper用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文