1、Jackson简介

Jackson是一个简单的基于Java的应用库,可以轻松的将Java对象转换为json对象和xml文档,同样也可以将json、xml转换为Java对象。Jackson依赖的jar包较少,简单易用性能高,社区活跃,更新速度快。

  • 特点
    • 容易使用,提供了高层次外观,简化常用的用例。
    • 无需创建映射,API提供了默认的映射大部分对象序列化。
    • 性能高,快速,低内存占用
    • 创建干净的json
    • 不依赖其他库
    • 代码开源

2、POM依赖

<!--前三个在使用SpringBoot时,引入了spring-boot-starter-web之后就不用再引了-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.9</version>
</dependency>
<!-- 支持xml格式 -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.9</version>
</dependency>

3、注解介绍

ObjectMapper objectMapper = new ObjectMapper();

3.1、@JsonAnyGetter和@JsonAnySetter

  • @JsonAnyGetter:该注解用于把可变的Map类型属性,当做标准属性;
  • @JsonAnySetter:该注解允许我们把一个可变的map属性作为标准属性, 在反序列过程中, 从Json字符串得到的属性值会加入到map属性中;

下例中,ExtendableBean实体有一个name属性和一组kay/value格式的可扩展属性:

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

    /* 1. cannot deserialize from Object value (no delegate- or property-based Creator)
     *    无默认构造函数,会导致反序列化失败
     *
     * 2.om.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: com.example.pojo.ExtendableBean["password"])
     *    Caused by: java.lang.NullPointerException
     *  无参构造函数中如果没有初始化 extMap 会报空指针异常
     */
    public ExtendableBean(){
        this.extMap = new HashMap<>();
    }

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

    public String getName() {
        return name;
    }

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

    @JsonAnyGetter
    public Map<String, String> getExtMap() {
        return extMap;
    }


    public void setExtMap(Map<String, String> extMap) {
        this.extMap = extMap;
    }

    // Unrecognized field "password" (class com.example.pojo.ExtendableBean), not marked as ignorable (2 known properties: "name", "extMap"])
    // @JsonAnySetter注解放错了位置
    @JsonAnySetter
    public void add(String key,String value){
        this.extMap.put(key,value);
    }

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

测试:

@Test
public void ExtendableBeanTest() throws JsonProcessingException {
    //序列化时使用getter
    //反序列化时使用setter
    ExtendableBean extendableBean = new ExtendableBean("小明");
    extendableBean.add("age","20");
    extendableBean.add("password","123456");
    String extStr = objectMapper.writeValueAsString(extendableBean);
    System.out.println("序列化:"+extStr);

    ExtendableBean ext = objectMapper.readerFor(ExtendableBean.class).readValue(extStr);
    assertEquals("小明",ext.getName());
    assertEquals("20",ext.getExtMap().get("age"));
    System.out.println("反序列化:"+ext);
}

3.2、@JsonProperty

  • 该注解可以指定属性在Json字符串中的名字;
  • 下例中在==非标准==的settergetter方法上使用该注解, 可以成功序列化和反序列化
public class MyBean {
    private String name;

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

    @JsonProperty("name")
    public void setTheName(String name) {
        this.name = name;
    }

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

测试:

@Test
public void MyBeanTest() throws JsonProcessingException {
    MyBean myBean = new MyBean();
    myBean.setTheName("小小");
    String myBeanStr = objectMapper.writeValueAsString(myBean);
    System.out.println("序列化:"+myBeanStr);
    MyBean myBeanE = objectMapper.readValue(myBeanStr,MyBean.class);
    System.out.println("反序列化:"+myBeanE);
}

3.3、@JsonGetter和 @JsonSetter

  • 这两个注解可以用来替换@JsonProperty的功能;
  • 二者结合与@JsonProperty实现的功能一样;
public class MyBean2 {
    private String name;

    @JsonGetter("name")
    public String getTheName() {
        return name;
    }

    @JsonSetter("name")
    public void setTheName(String name) {
        this.name = name;
    }

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

测试:

@Test
public void MyBean2Test() throws JsonProcessingException{
    MyBean2 myBean = new MyBean2();
    myBean.setTheName("小小");
    String myBeanStr = objectMapper.writeValueAsString(myBean);
    System.out.println("序列化:"+myBeanStr);
    MyBean2 myBeanE = objectMapper.readValue(myBeanStr,MyBean2.class);
    System.out.println("反序列化:"+myBeanE);
}

3.4、@JsonPropertyOrder

  • 该注解可以指定实体属性序列化后的顺序
//@JsonPropertyOrder({"name","age","id"})
@JsonPropertyOrder(alphabetic=true)
public class OrderBean {
    private String id;
    private Integer age;
    private String name;

    public OrderBean() {}

    public OrderBean(String id, Integer age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public String getId() {
        return id;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

测试:

@Test
public void OrderBeanTest() throws JsonProcessingException {
    OrderBean orderBean = new OrderBean("002",20,"小王");
    String orderBeanStr = objectMapper.writeValueAsString(orderBean);
    System.out.println("序列化:"+orderBeanStr);

    OrderBean odb = objectMapper.readValue(orderBeanStr,OrderBean.class);
    System.out.println("反序列化:"+odb);
    //未加@JsonPropertyOrder时的顺序
    //序列化:{"id":"002","age":20,"name":"小王"}
    //反序列化:OrderBean{id='002', age=20, name='小王'}

    //加上@JsonPropertyOrder({"name","age","id"})时的顺序
    //序列化:{"name":"小王","age":20,"id":"002"}
    //反序列化:OrderBean{id='002', age=20, name='小王'}

    //加上@JsonPropertyOrder({"name","age","id"})时的顺序
    //序列化:{"age":20,"id":"002","name":"小王"}
    //反序列化:OrderBean{id='002', age=20, name='小王'}
}

3.5、@JsonValue

  • 加在谁的上面就只序列化谁;
    • 加方法:序列化方法的返回值;如果方法的返回值为void则正常序列化这个Bean
    • 加属性:序列化属性;
  • 在一个Bean类中只能存在一个@JsonValue注解
    • 不能同时加在两个属性上;
    • 不能同时加在两个方法上;
    • 一属性一方法也不行;
    • 都会产生竞争;
public class UserJsonValue {

    private String id;

    private String name;

    @JsonValue
    public void toJson(){
        String s = id+":"+name;
        System.out.println(s);
    }


    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

测试:

@Test
public void UserJsonValueTest() throws JsonProcessingException {
    UserJsonValue userJsonValue = new UserJsonValue();
    userJsonValue.setId("0");
    userJsonValue.setName("asc");
    String value = objectMapper.writeValueAsString(userJsonValue);
    System.out.println("序列化:"+value);
}

3.6、@JsonRootName

  • 定义一个根key
// @JsonRootName("userRoot")
@JsonRootName(value = "user", namespace = "alibaba")
public class UserJsonRoot {

	private String userName;

	private int age;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

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

	public int getAge() {
		return age;
	}

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

测试:

//测试:@JsonRootName("userRoot")
@Test
public void JsonRootNameTest() throws JsonProcessingException {
    UserJsonRoot userJsonRoot = new UserJsonRoot();
    userJsonRoot.setUsername("abc");
    userJsonRoot.setAge(20);

    objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);//加上才有效果
    String rootStr = objectMapper.writeValueAsString(userJsonRoot);
    System.out.println("序列化:"+rootStr);
    //序列化:{"user":{"userName":"abc","age":20}}
    //和正常的比:多出了一层user

    objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);//加上才能反序列化
    UserJsonRoot u2 = objectMapper.readValue(rootStr,UserJsonRoot.class);
    System.out.println("反序列化:"+u2);
    //反序列化:UserJsonRoot{userName='abc', age=20}
}
//测试:@JsonRootName(value = "user", namespace = "alibaba")
@Test
public void JsonRootNameTest2() throws JsonProcessingException {
    UserJsonRoot userJsonRoot = new UserJsonRoot();
    userJsonRoot.setUsername("abc");
    userJsonRoot.setAge(20);

    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    String xmlStr = xmlMapper.writeValueAsString(userJsonRoot);
    System.out.println("XML形式序列化:"+xmlStr);
    //XML形式序列化:<user xmlns="alibaba"><userName xmlns="">abc</userName><age xmlns="">20</age></user>


    // xmlMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);//XML形式不加这个
    UserJsonRoot u2 = xmlMapper.readValue(xmlStr,UserJsonRoot.class);
    System.out.println("反序列化:"+u2);
    //XML形式反序列化:反序列化:UserJsonRoot{userName='abc', age=20}


    //序列化为XML文件
    xmlMapper.writeValue(new File("simple_bean.xml"), userJsonRoot);

    //反序列化XML文件
    String fileStr = Files.lines(Paths.get("simple_bean.xml")).collect(Collectors.joining());
    System.out.println("读取文件:"+fileStr);
    UserJsonRoot deUsJsRoot = xmlMapper.readValue(fileStr, UserJsonRoot.class);
    System.out.println("序列化:"+deUsJsRoot);
}

3.7、@JsonInclude

  • 该注解在序列化时会排除属性值是空值(empty或null)、没有默认值的属性。

    • ALWAYS: 这个是默认策略,任何情况下都序列化该字段,和不写这个注解是一样的效果。
    • NON_NULL:即如果加该注解的字段为null,那么就不序列化这个字段了。
    • NON_ABSENT:
    • NON_EMPTY:这个属性包含NON_NULL,NON_ABSENT之后还包含如果字段为空也不序列化。这个也比较常用
    • NON_DEFAULT:如果字段是默认值的话就不序列化。
    • CUSTOM:
    • USE_DEFAULTS:
  • 可作用在类和属性上

//@JsonInclude(JsonInclude.Include.NON_DEFAULT)
//@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class JsonIncludeBean {
    private int anInt;
    private Integer anInt2;

    private double anDouble;
    private Double anDouble2;

    private char anChar;
    private Character anChar2;

    private byte aByte;
    private Byte aByte2;

    private short aShort;
    private Short aShort2;

    private long aLong;
    private Long aLong2;

    private float aFloat;
    private Float aFloat2;

    private boolean aBoolean;
    private Boolean aBoolean2;

    private String string;

    //getter setter
}

测试:

@Test
public void JsonIncludeBeanTest() throws JsonProcessingException {
    JsonIncludeBean jsonIncludeBean = new JsonIncludeBean();
    String asString = objectMapper.writeValueAsString(jsonIncludeBean);
    //System.out.println("默认值序列化:"+asString);
    //{"anInt":0,"anInt2":null,"anDouble":0.0,"anDouble2":null,"anChar":"\u0000",
    // "anChar2":null,"aByte":0,"aByte2":null,"aShort":0,"aShort2":null,"aLong":0,
    // "aLong2":null,"aFloat":0.0,"aFloat2":null,"aBoolean":false,"aBoolean2":null,"string":null}

    //JsonInclude.Include.NON_NULL
    //System.out.println("序列化(排除非空):"+asString);
    //{"anInt":0,"anDouble":0.0,"anChar":"\u0000","aByte":0,"aShort":0,"aLong":0,"aFloat":0.0,"aBoolean":false}

    //@JsonInclude(JsonInclude.Include.NON_DEFAULT)
    //System.out.println("序列化(排除默认值):"+asString);
    //序列化(排除默认值):{}

    //jsonIncludeBean.setString("");
    //String str = objectMapper.writeValueAsString(jsonIncludeBean);
    //@JsonInclude(JsonInclude.Include.NON_DEFAULT)
    //System.out.println("序列化(排除默认值):"+str);
    //序列化(排除默认值):{"string":""}

    jsonIncludeBean.setString("");
    String str2 = objectMapper.writeValueAsString(jsonIncludeBean);
    System.out.println("序列化(属性为空字符串或NULL都不序列化):"+str2);
    //序列化(属性为空字符串或NULL都不序列化):
    // {"anInt":0,"anDouble":0.0,"anChar":"\u0000","aByte":0,"aShort":0,"aLong":0,
    // "aFloat":0.0,"aBoolean":false}
}
  • 总结:如果使用此注解进行序列化,最好使用包装类型

3.8、@JsonIgnore

  • 该注解用于属性级别, 用于标明一个属性可以被Jackson忽略
public class BeanIgnore {
    @JsonIgnore
    private int id;

    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

测试:

@Test
public void BeanIgnoreTest() throws JsonProcessingException {
    BeanIgnore beanIgnore = new BeanIgnore();
    beanIgnore.setId(12);
    beanIgnore.setName("adsd");
    System.out.println(objectMapper.writeValueAsString(beanIgnore));
}

3.9、@JsonIgnoreProperties

  • 该注解是一个类级别的注解, 标记一个或多个属性被Jackson忽略
@JsonIgnoreProperties({"id"})
//@JsonIgnoreProperties({"id", "name"})
public class BeanWithIgnore {
    private int id;
    private String name;
    private String pass;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    @Override
    public String toString() {
        return "BeanWithIgnore{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pass='" + pass + '\'' +
                '}';
    }
}

测试:

@Test
public void BeanWithIgnoreTest() throws JsonProcessingException{
    BeanWithIgnore beanWithIgnore = new BeanWithIgnore();
    beanWithIgnore.setId(12);
    beanWithIgnore.setName("qaz");
    beanWithIgnore.setPass("123");
    String str = objectMapper.writeValueAsString(beanWithIgnore);
    //@JsonIgnoreProperties({"id"})
    System.out.println("序列化:"+str);
    //序列化:{"name":"qaz","pass":"123"}

    //@JsonIgnoreProperties({"id", "name"})
    //System.out.println("序列化:"+str);
    //序列化:{"pass":"123"}
}

3.10、@JsonIgnoreType

  • 该注解标记类型是注解作用的类型的属性都会被忽略
    必须作用于类, 标明以该类为指定类型的属性都会被Jackson忽略
public class BeanWithIgnoreType {
    private Integer xid;
    private Name name;

    public BeanWithIgnoreType() {
    }

    public BeanWithIgnoreType(Integer xid, Name name) {
        this.xid = xid;
        this.name = name;
    }

    @JsonIgnoreType
    public static class Name{
        private String firstName;
        private String secondName;

        public Name(String firstName, String secondName) {
            this.firstName = firstName;
            this.secondName = secondName;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getSecondName() {
            return secondName;
        }

        public void setSecondName(String secondName) {
            this.secondName = secondName;
        }

        @Override
        public String toString() {
            return "Name{" +
                    "firstName='" + firstName + '\'' +
                    ", secondName='" + secondName + '\'' +
                    '}';
        }
    }

    public Integer getXid() {
        return xid;
    }

    public void setXid(Integer xid) {
        this.xid = xid;
    }

    public Name getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "BeanWithIgnoreType{" +
                "xid=" + xid +
                ", name=" + name +
                '}';
    }
}

测试:

@Test
public void BeanWithIgnoreTypeTest()  throws JsonProcessingException, ParseException {
    BeanWithIgnoreType.Name name = new BeanWithIgnoreType.Name("John", "Doe");
    BeanWithIgnoreType beanWithIgnoreType = new BeanWithIgnoreType(1, name);
    String result = objectMapper.writeValueAsString(beanWithIgnoreType);
    System.out.println("序列化:"+result);
    //序列化:{"xid":1}

    BeanWithIgnoreType b2 = objectMapper.readValue(result,BeanWithIgnoreType.class);
    System.out.println("反序列化:"+b2);
    //序列化:{"xid":1}
    //反序列化:BeanWithIgnoreType{xid=1, name=null}
}

3.11、@JsonIgnore

  • 该注解用于属性级别, 用于标明一个属性可以被Jackson忽略

@JsonIgnoreProperties测试方式一样,不在重复


3.12、@JsonSerialize和@JsonDeserialize

  • @JsonSerialize:自定义序列化器;
  • @JsonDeserialize:自定义反序列化器;
public class Event {
    private String name;

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

    public String getName() {
        return name;
    }

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

    public Date getEventDate() {
        return eventDate;
    }

    public void setEventDate(Date eventDate) {
        this.eventDate = eventDate;
    }
}
public class CustomDateSerializer extends StdSerializer<Date> {
    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    public CustomDateSerializer() { this(null); }
    public CustomDateSerializer(Class<Date> t) { super(t); }
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2)
            throws IOException {
        gen.writeString(formatter.format(value));
    }
}
public class CustomDateDeserializer extends StdDeserializer<Date> {
    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    public CustomDateDeserializer(){
        super(Date.class);
    }

    public CustomDateDeserializer(Class<Date> cv){
        super(cv);
    }

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        if(StringUtils.isEmpty(p.getText())){
            return null;
        }
        try {
            return FORMATTER.parse(p.getText());
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}

测试:

@Test
public void CustomTest() throws JsonProcessingException {
    Event event = new Event();
    event.setEventDate(new Date());
    event.setName("createtime");
    String str = objectMapper.writeValueAsString(event);
    System.out.println("序列化:"+str);
    //序列化:{"name":"createtime","eventDate":"2020-08-27 02:30:59"}

    System.out.println("反序列化:"+objectMapper.readValue(str,Event.class));
    //反序列化:Event{name='createtime', eventDate=Thu Aug 27 02:30:59 CST 2020}
}

3.13、@JsonCreator

  • 该注解可以调整反序列化时构造器/构造工厂的行为
  • 当我们需要==反序列化的Json字符串==和目标实体类不完全匹配时, 这个注解非常有用;
public class BeanWithCreator {
    @JsonProperty("id")
    private int id;
    @JsonProperty("theName")
    private String name;

    @JsonCreator
    public BeanWithCreator() {
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

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

测试:

@Test
public void CreatorTest() throws JsonProcessingException{
    String str = "{'id':1,'theName':'My bean'}";
    //解决单引号问题如果不加这个,改成这样“"{\"name\":\"My bean\"}"
    objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    //objectMapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
    System.out.println("反序列化:"+objectMapper.readerFor(BeanWithCreator.class).readValue(str));
    //反序列化:BeanWithCreator{id=1, name='My bean'}
}

3.14、@JsonAlias

  • 该注解在反序列化过程中为属性定义一个或多个别名
public class AliasBean {
    @JsonAlias({ "fName", "f_name" })
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "AliasBean{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

测试:

@Test
public void AliasTest() throws JsonProcessingException {
    String json = "{\"fName\": \"John\", \"lastName\": \"Green\"}";
    AliasBean aliasBean = new ObjectMapper().readerFor(AliasBean.class).readValue(json);
    System.out.println("反序列化:"+aliasBean);
    //反序列化:AliasBean{firstName='John', lastName='Green'}

    json = "{\"f_name\": \"John\", \"lastName\": \"Green\"}";
    aliasBean = new ObjectMapper().readerFor(AliasBean.class).readValue(json);
    System.out.println("反序列化:"+aliasBean);
    //反序列化:AliasBean{firstName='John', lastName='Green'}
}

3.15、@JsonAutoDetect

  • 该注解可以覆盖属性是否可见的默认语义, 比如对于不可见的private序列化时变成可见的
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class PrivateBean {
    private int id;
    private String name;
}

序列化过程:

public void whenSerializingUsingJsonAutoDetect_thenCorrect()  throws JsonProcessingException {
    PrivateBean bean = new PrivateBean(1, "My bean"); 
    String result = new ObjectMapper().writeValueAsString(bean);   
    assertThat(result, containsString("1"));
    assertThat(result, containsString("My bean"));
}

3.16、@JsonFormat

  • 该注解指定序列化日期和时间时的格式
public class EventFormat {
    private String name;

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

    public String getName() {
        return name;
    }

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

    public Date getEventDate() {
        return eventDate;
    }

    public void setEventDate(Date eventDate) {
        this.eventDate = eventDate;
    }

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

测试:

@Test
public void EventFormatTest() throws JsonProcessingException{
    EventFormat eventFormat = new EventFormat();
    eventFormat.setEventDate(new Date());
    eventFormat.setName("sd");
    String str = objectMapper.writeValueAsString(eventFormat);
    System.out.println("序列化:"+str);
    //序列化:{"name":"sd","eventDate":"2020-08-27 08:42:10"}

    EventFormat ev2 = objectMapper.readValue(str,EventFormat.class);
    System.out.println("反序列化:"+ev2);
}

3.17、 @JsonAppend

该注解用来给一个被序列化的对象添加一个虚拟属性. 这个功能非常有用, 尤其是当我们想直接在Json字符串中添加额外的信息时, 不再需要修改类的定义. 举例来说, 它可以很方便的在Json文档中插入bean的版本信息, 而不需要bean提供对应的属性.

@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
public class BeanWithAppend {
    private int id;
    private String name;

    public BeanWithAppend() {
    }

    public BeanWithAppend(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

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

测试:

@Test
	public void BeanWithAppendTest() throws JsonProcessingException {
		BeanWithAppend bean = new BeanWithAppend(2, "Bean With Append Annotation");
		ObjectWriter writer = objectMapper.writerFor(BeanWithAppend.class).withAttribute("version", "1.0");
		String jsonString = writer.writeValueAsString(bean);
		System.out.println("序列化:"+jsonString);
		//序列化:{"id":2,"name":"Bean With Append Annotation","version":"1.0"}
	}

待整理

https://blog.csdn.net/blwinner/article/details/98532847

5、复杂类型处理

public static final ObjectMapper JsonMapper = new ObjectMapper();

/**
 * String类型的javaType
 */
public static final JavaType StringJavaType = JsonMapper.getTypeFactory().constructType(String.class);

/**
 * 支持Map<String,String>
 */
public static final JavaType StringStringMap = JsonMapper.getTypeFactory().constructMapType(HashMap.class, String.class, String.class);

/**
 * 支持Map<String,Map<String,String>>
 */
public static final JavaType StringStringStringMap = JsonMapper.getTypeFactory().constructMapType(HashMap.class,
		StringJavaType, StringStringMap);

/**
 * 支持Map<String,Map<String,Map<String,String>>>
 */
public static final JavaType StringStringStringStringMap = JsonMapper.getTypeFactory()
		.constructMapType(HashMap.class, StringJavaType, StringStringStringMap);

/**
 * 支持List<Object>
 */
public static final JavaType ListObject = JsonMapper.getTypeFactory().constructCollectionType(ArrayList.class, Object.class);

/**
 * 支持List<List<Object>>
 */
public static final JavaType ListListObject = JsonMapper.getTypeFactory().constructCollectionType(ArrayList.class, ListObject);

5、直接构建JsonStr及Json的解析

@Test
public void createObject() throws JsonProcessingException {
   HashMap<String,Object> hashMap = new HashMap<String,Object>(){{
         put("a",1);
         put("b","a");
      }};
   String hashJsonStr = objectMapper.writeValueAsString(hashMap);
   System.out.println("序列化:"+hashJsonStr);//序列化:{"a":1,"b":"a"}


   HashMap<?,?> DeseHashMap = objectMapper.readValue(hashJsonStr, HashMap.class);
   System.out.println("反序列化:"+DeseHashMap.get("a"));//反序列化:1
   System.out.println("反序列化:"+DeseHashMap.get("b"));//反序列化:1
}