java:jackson 一:Jackson Annotation

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。java:jackson 一:Jackson Annotation,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

java:jackson 一:Jackson Annotation

1 前言

参考文档地址:

https://www.baeldung.com/jackson

https://www.baeldung.com/jackson-annotations

2 使用

2.1 Jackson Serialization Annotations

jackson 序列化注解


2.1.1 @JsonAnyGetter

The @JsonAnyGetter annotation allows for the flexibility of using a Map field as standard properties.

package com.xiaoxu.test.jackson;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.text.StringEscapeUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author xiaoxu
 * @date 2022-12-21
 * spring_boot:com.xiaoxu.test.jackson.TestJaskSon
 */
public class TestJaskSon {

    public static void main(String[] args) throws Exception{
        ExtendableBean bean = new ExtendableBean("My bean");
        bean.add("attr1", "val1");
        bean.add("attr2", "val2");

        System.out.println(bean);

        String result = new ObjectMapper().writeValueAsString(bean);
        System.out.println(result);

        String a = "{\\\"name\\\":\\\"xiaoxu\\\",\\\"age\\\":\\\"27\\\"}";
        String s = StringEscapeUtils.unescapeJava(a);
        System.out.println(s);
        UseRR useRR = JSON.parseObject(s, UseRR.class);
        System.out.println(useRR);
    }
}

class UseRR{
    String name;

    String age;

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

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

    @Override
    public String toString() {
        return "UseRR{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

class ExtendableBean {
    public String name;
    private Map<String, String> properties;

    ExtendableBean(String name){
        this.name = name;
        this.properties = new HashMap<>();
    }

    public void add(String key,String value){
        this.properties.put(key,value);
    }

    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }

    @Override
    public String toString() {
        return "ExtendableBean{" +
                "name='" + name + '\'' +
                ", properties=" + properties +
                '}';
    }
}
ExtendableBean{name='My bean', properties={attr2=val2, attr1=val1}}
{"name":"My bean","attr2":"val2","attr1":"val1"}
{"name":"xiaoxu","age":"27"}
UseRR{name='xiaoxu', age='27'}

可见,@JsonAnyGetter加在Map属性的get方法上时,打印的json字符串为将Map属性的key、value也直接展示在json结果中了。


2.1.2 @JsonGetter

The @JsonGetter annotation is an alternative to the @JsonProperty annotation, which marks a method as a getter method.

先观察@JsonProperty的使用:

如下DTO的name属性的set和get方法名称,不是传统的setter、getter方法名称:

package test.jackson;

import lombok.AllArgsConstructor;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonDTO
 */
@AllArgsConstructor
public class JacksonDTO {
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getMyName() {
        return name;
    }

    public void setMyName(String name) {
        this.name = name;
    }
}
package test.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonAnnotationTest
 */
public class JacksonAnnotationTest {
    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
    }

    public static void demo1() throws Exception{
        JacksonDTO jacksonDTO = new JacksonDTO(1,"xiaoxu");
        System.out.println(objectMapper.writeValueAsString(jacksonDTO));
    }

    public static void main(String[] args) throws Exception{
        demo1();
    }

}

上述执行结果如下,可见序列化后,不为name,是myName:

{
  "id" : 1,
  "myName" : "xiaoxu"
}

使用@JsonProperty:

package test.jackson;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;


/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonDTO
 */
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class JacksonDTO {
    @JsonProperty(value = "mid")
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @JsonProperty(value = "xName")
    public String getMyName() {
        return name;
    }

//    @JsonProperty(value = "xName")
    public void setMyName(String name) {
        this.name = name;
    }
}
package test.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonAnnotationTest
 */
public class JacksonAnnotationTest {
    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
    }

    public static void demo1() throws Exception{
        JacksonDTO jacksonDTO = new JacksonDTO(1,"xiaoxu");
        System.out.println(objectMapper.writeValueAsString(jacksonDTO));
        /* 反序列化的前提:需要有无参构造方法,否则报错:
        *
        * (no Creators, like default constructor, exist):
        * cannot deserialize from Object value (no delegate- or property-based Creator)
        *  */
        JacksonDTO jacksonDTO1 = objectMapper.readerFor(JacksonDTO.class)
                .readValue(objectMapper.writeValueAsString(jacksonDTO));
        System.out.println(jacksonDTO1);
    }

    public static void main(String[] args) throws Exception{
        demo1();
    }

}

序列化结果:

{
  "mid" : 1,
  "xName" : "xiaoxu"
}
JacksonDTO(id=1, name=xiaoxu)

@JsonGetter可替代如上@JsonProperty注解使用:

在这里插入图片描述

再次执行,序列化的效果一致:

在这里插入图片描述


2.1.3 @JsonPropertyOrder

We can use the @JsonPropertyOrder annotation to specify the order of properties on serialization.

@JsonPropertyOrder主要是更新序列化后的结果的字段顺序,如果同时存在使用了@JsonProperty注解,必须按照@JsonProperty注解的value设置值,才能更新顺序成功(无法匹配则没有效果)。

@ToString
@AllArgsConstructor
@NoArgsConstructor
@JsonPropertyOrder(value = {"xxName","mid"})
public class JacksonDTO {
    @JsonProperty(value = "mid")
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @JsonGetter(value = "xxName")
    public String getMyName() {
        return name;
    }

//    @JsonProperty(value = "xName")
    public void setMyName(String name) {
        this.name = name;
    }
}

再次执行,DTO的字段顺序改变:

在这里插入图片描述


2.1.4 @JsonRawValue

The @JsonRawValue annotation can instruct Jackson to serialize a property exactly as is.

@ToString
@AllArgsConstructor
@NoArgsConstructor
/* 序列化时,有getter方法即可 */
@Getter
public class JacksonDTO1 {
    int id;
    String name;
    @JsonRawValue
    String jsonData;
}
JacksonDTO1 jacksonDTO1 = new JacksonDTO1(1,"xiaoxu","{\"myName\":\"xiaoxu\",\"age\":\"55\"}");
System.out.println(objectMapper.writeValueAsString(jacksonDTO1));

执行结果:

{
  "id" : 1,
  "name" : "xiaoxu",
  "jsonData" : {"myName":"xiaoxu","age":"55"}
}

2.1.5 @JsonValue

@JsonValue indicates a single method that the library will use to serialize the entire instance.

For example, in an enum, we annotate the getName with @JsonValue so that any such entity is serialized via its name.

enum JackEnum{
    Study("study",1234);

    private String code;
    private long value;

    JackEnum(String code, long value){
        this.code = code;
        this.value = value;
    }

    @JsonValue
    public String getCode() {
        return code;
    }

    public long getValue() {
        return value;
    }
}
System.out.println(objectMapper.writeValueAsString(JackEnum.Study));

执行结果:

"study"

2.1.6 @JsonRootName

The @JsonRootName annotation is used, if wrapping is enabled, to specify the name of the root wrapper to be used.

Wrapping means that instead of serializing a User to something like:

@ToString
@AllArgsConstructor
@NoArgsConstructor
/* 序列化时,有getter方法即可 */
@Getter
@JsonRootName(value = "specialPerson")
class JacksonDTO2 {
    int id;
    String name;
}
/* 不增加 objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
* @JsonRootName(value = "specialPerson") 将不会生效
*  */
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
JacksonDTO2 jacksonDTO2 = new JacksonDTO2(1,"xiaoxu");
System.out.println(objectMapper.writeValueAsString(jacksonDTO2));

执行结果:

{
  "specialPerson" : {
    "id" : 1,
    "name" : "xiaoxu"
  }
}

2.1.7 @JsonSerialize

We’re going to use @JsonSerialize to serialize the eventDate property with a CustomDateSerializer:

该注解常用于和自定义序列化(或类似@JsonDeserialize,与自定义反序列化)器一同使用

使用参考如下:

https://blog.csdn.net/a232884c/article/details/128418713

2.2 Jackson Deserialization Annotations

jackson 反序列化注解


2.2.1 @JsonCreator

We can use the @JsonCreator annotation to tune the constructor/factory used in deserialization.

It’s very useful when we need to deserialize some JSON that doesn’t exactly match the target entity we need to get.

去掉@JsonCreator,只使用@JsonProperty,效果是一样的:

@ToString
class JacksonDTO3 {
    int id;
    String name;

    /* 构造方法为反序列化时的myName,映射为name */
    @JsonCreator
    public JacksonDTO3(@JsonProperty("id") int id,
                       @JsonProperty("myName") String name){
        this.id = id;
        this.name = name;
    }
}
String value = "{\"id\":\"123\",\"myName\":\"xiaoxu\"}";
JacksonDTO3 dto3 = objectMapper.readerFor(JacksonDTO3.class)
        .readValue(value);
System.out.println(dto3);

执行结果:

JacksonDTO3(id=123, name=xiaoxu)

2.2.2 @JacksonInject

@JacksonInject indicates that a property will get its value from the injection and not from the JSON data.

In the following example, we use @JacksonInject to inject the property id:

@ToString
class JacksonDTO4 {
    @JacksonInject
    int id;
    String name;

    /* id 是注入的, 但是name反序列化时,取的jsonData中的,
    * 必须加上getter方法,否则将会抛出异常
    *  */
    public String getName() {
        return name;
    }
}
String value = "{\"name\":\"xiaoxu\"}";
InjectableValues inject = new InjectableValues.Std().addValue(int.class, 666);
JacksonDTO4 dto4 = objectMapper.reader(inject)
        .forType(JacksonDTO4.class)
        .readValue(value);
System.out.println(dto4);

执行结果:

JacksonDTO4(id=666, name=xiaoxu)

2.2.3 @JsonAnySetter

@JsonAnySetter allows us the flexibility of using a Map as standard properties. On deserialization, the properties from JSON will simply be added to the map.

@ToString
class ExtendableBean {
    public String name;
    private final Map<String, String> properties = new HashMap<>();

    @JsonAnySetter
    public void add(String key, String value) {
        properties.put(key, value);
    }
}
String json
        = "{\"name\":\"xiaoxu\",\"attr2\":\"val2\",\"attr1\":\"val1\"}";

ExtendableBean bean = objectMapper
        .readerFor(ExtendableBean.class)
        .readValue(json);
System.out.println(bean);

执行结果:

ExtendableBean(name=xiaoxu, properties={attr2=val2, attr1=val1})

2.2.4 @JsonSetter

@JsonSetter is an alternative to @JsonProperty that marks the method as a setter method.

This is incredibly useful when we need to read some JSON data, but the target entity class doesn’t exactly match that data, and so we need to tune the process to make it fit.

此注解和@JsonGetter效果类似,只是用于的是反序列化

@ToString
class JacksonDTO5 {
    int id;
    String name;

    /* 反序列化时,id 有setter或者getter方法均可 */
    public void setId(int id) {
        this.id = id;
    }

    @JsonSetter("name")
    public void setMyName(String name) {
        this.name = name;
    }
}
String value = "{\"id\":\"123999\",\"name\":\"xiaoxu\"}";
JacksonDTO5 dto5 = objectMapper.readerFor(JacksonDTO5.class)
        .readValue(value);
System.out.println(dto5);

执行结果:

JacksonDTO5(id=123999, name=xiaoxu)

2.2.5 @JsonDeserialize

@JsonDeserialize indicates the use of a custom deserializer.

该注解@JsonDeserialize用于和自定义反序列化器一同使用

使用参考如下:

https://blog.csdn.net/a232884c/article/details/128407205

2.2.6 @JsonAlias

The @JsonAlias defines one or more alternative names for a property during deserialization.

@ToString
class JacksonDTO6 {
    int id;
    @JsonAlias(value = {"f_name","frName"})
    String fruitName;

    /* 反序列化时,id 有setter或者getter方法均可 */
    public void setId(int id) {
        this.id = id;
    }

    /* 反序列化时,fruitName 有setter或者getter方法均可 */
    public String getFruitName() {
        return fruitName;
    }
}
String value = "{\"id\":\"123888\",\"frName\":\"xiaoxu\"}";
JacksonDTO6 dto6 = objectMapper.readerFor(JacksonDTO6.class)
        .readValue(value);
System.out.println(dto6);

执行结果:

JacksonDTO6(id=123888, fruitName=xiaoxu)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192099.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!