Use Jackson to customize the serialization/deserialization of a field (Jackson - Decide What Fields Get Serialized/Deserialized)

A Public Field

When there are get and set methods, both serialization and deserialization are supported

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyDtoAccessLevel {
    
    
    private String stringValue;
    int intValue;
    protected float floatValue;
    public boolean booleanValue;
}
ObjectMapper mapper = new ObjectMapper();
MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();
String dtoAsString = mapper.writeValueAsString(dtoObject);
System.out.println(dtoAsString);

String jsonAsString = "{\"stringValue\":\"dtoString\"}";
MyDtoAccessLevel dtoObject1 = mapper.readValue(jsonAsString, MyDtoAccessLevel.class);
System.out.println(dtoObject1);

执行结果
{
    
    "stringValue":null,"intValue":0,"floatValue":0.0,"booleanValue":false}
MyDtoAccessLevel(stringValue=dtoString, intValue=0, floatValue=0.0, booleanValue=false)

When there is no get or set method, serialization and deserialization only support public

public class MyDtoAccessLevel {
    
    
    private String stringValue;
    int intValue;
    protected float floatValue;
    public boolean booleanValue;

    @Override
    public String toString() {
    
    
        return "MyDtoAccessLevel{" + "stringValue='" + stringValue + '\'' + ", intValue=" + intValue + ", floatValue=" + floatValue + ", booleanValue=" + booleanValue + '}';
    }
}
ObjectMapper mapper = new ObjectMapper();
MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();
String dtoAsString = mapper.writeValueAsString(dtoObject);
System.out.println(dtoAsString);

String jsonAsString = "{\"booleanValue\":false}";
MyDtoAccessLevel dtoObject1 = mapper.readValue(jsonAsString, MyDtoAccessLevel.class);
System.out.println(dtoObject1);

结果
{
    
    "booleanValue":false}
MyDtoAccessLevel{
    
    stringValue='null', intValue=0, floatValue=0.0, booleanValue=false}

Deserialization only supports public fields. If the JSON string contains other fields, it cannot be recognized otherwise, and an error will be reported.

String jsonAsString = "{\"booleanValue\":false,\"stringValue\":\"dtoString\"}";
MyDtoAccessLevel dtoObject1 = mapper.readValue(jsonAsString, MyDtoAccessLevel.class);
System.out.println(dtoObject1);

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stringValue" (class javabasic.enumprac.MyDtoAccessLevel), not marked as ignorable (one known property: "booleanValue"])
 at [Source: (String)"{"booleanValue":false,"stringValue":"dtoString"}"; line: 1, column: 38] (through reference chain: javabasic.enumprac.MyDtoAccessLevel["stringValue"])

A Getter Makes a Non-Public Field Serializable and Deserializable

public class MyDtoWithGetter {
    
    
    private String stringValue;
    private int intValue;

    public String getStringValue() {
    
    
        return stringValue;
    }

    @Override
    public String toString() {
    
    
        return "MyDtoWithGetter{" + "stringValue='" + stringValue + '\'' + ", intValue=" + intValue + '}';
    }
}

Non-Public Field with get method supports serialization and deserialization

ObjectMapper mapper = new ObjectMapper();
MyDtoWithGetter dtoObject = new MyDtoWithGetter();
String dtoAsString = mapper.writeValueAsString(dtoObject);
System.out.println(dtoAsString);

String jsonAsString = "{\"stringValue\":\"dtoString\"}";
MyDtoWithGetter dtoObject1 = mapper.readValue(jsonAsString, MyDtoWithGetter.class);
System.out.println(dtoObject1);

结果
{
    
    "stringValue":null}
MyDtoWithGetter{
    
    stringValue='dtoString', intValue=0}

When deserializing Json strings, only Non-Public Fields with get methods are supported, otherwise it cannot be parsed and an error is reported

String jsonAsString = "{\"intValue\":11,\"stringValue\":\"dtoString\"}";
MyDtoWithGetter dtoObject1 = mapper.readValue(jsonAsString, MyDtoWithGetter.class);

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "intValue" (class javabasic.enumprac.MyDtoWithGetter), not marked as ignorable (one known property: "stringValue"])
 at [Source: (String)"{"intValue":11,"stringValue":"dtoString"}"; line: 1, column: 15] (through reference chain: javabasic.enumprac.MyDtoWithGetter["intValue"])

A Setter Makes a Non-Public Field Deserializable Only

public class MyDtoWithSetter {
    
    
    private String stringValue;
    private int intValue;

    public void setIntValue(int intValue) {
    
    
        this.intValue = intValue;
    }

    @Override
    public String toString() {
    
    
        return "MyDtoWithSetter{" + "stringValue='" + stringValue + '\'' + ", intValue=" + intValue + '}';
    }
}

the setter should only make the field deserializable, but not serializable:

ObjectMapper mapper = new ObjectMapper();
MyDtoWithSetter  dtoObject = new MyDtoWithSetter ();
String dtoAsString = mapper.writeValueAsString(dtoObject);
System.out.println(dtoAsString);

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class javabasic.enumprac.MyDtoWithSetter and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

It can only parse attributes with set methods, otherwise an error will be reported

ObjectMapper mapper = new ObjectMapper();
String jsonAsString = "{\"intValue\":1}";
MyDtoWithSetter dtoObject1 = mapper.readValue(jsonAsString, MyDtoWithSetter.class);
System.out.println(dtoObject1);

MyDtoWithSetter{
    
    stringValue='null', intValue=1}
ObjectMapper mapper = new ObjectMapper();
String jsonAsString = "{\"stringValue\":\"dtoString\",\"intValue\":\"22\"}";
MyDtoWithSetter dtoObject1 = mapper.readValue(jsonAsString, MyDtoWithSetter.class);
System.out.println(dtoObject1);

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stringValue" (class javabasic.enumprac.MyDtoWithSetter), not marked as ignorable (one known property: "intValue"])
 at [Source: (String)"{"stringValue":"dtoString","intValue":"22"}"; line: 1, column: 17] (through reference chain: javabasic.enumprac.MyDtoWithSetter["stringValue"])

Make All Fields Globally Serializable

public class MyDtoAccessLevel {
    
    
    private String stringValue;
    int intValue;
    protected float floatValue;
    public boolean booleanValue;

    @Override
    public String toString() {
    
    
        return "MyDtoAccessLevel{" + "stringValue='" + stringValue + '\'' + ", intValue=" + intValue + ", floatValue=" + floatValue + ", booleanValue=" + booleanValue + '}';
    }
}
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();

String dtoAsString = mapper.writeValueAsString(dtoObject);
System.out.println(dtoAsString);

{
    
    "stringValue":null,"intValue":0,"floatValue":0.0,"booleanValue":false}

Change the Name of a Property on Serialization/Deserialization

for the same output code

 ObjectMapper mapper = new ObjectMapper();
 MyDto dtoObject = new MyDto();
 dtoObject.setStringValue("a");
 
 String dtoAsString = mapper.writeValueAsString(dtoObject);
 System.out.println(dtoAsString);
public class MyDto {
    
    
    private String stringValue;

    public MyDto() {
    
    
        super();
    }

    public String getStringValue() {
    
    
        return stringValue;
    }

    public void setStringValue(String stringValue) {
    
    
        this.stringValue = stringValue;
    }
}

结果
{
    
    "stringValue":"a"}
public class MyDto {
    
    
    private String stringValue;

    public MyDto() {
    
    
        super();
    }

    @JsonProperty("strVal")
    public String getStringValue() {
    
    
        return stringValue;
    }

    public void setStringValue(String stringValue) {
    
    
        this.stringValue = stringValue;
    }
}

结果
{
    
    "strVal":"a"}

Ignore a Field on Serialization or Deserialization

Further reading: Jackson Ignore Properties on Marshalling

Disable serialization of the field by adding the @JsonIgnore annotation on the getter and enable deserialization of the field by applying the @JsonProperty annotation on the setter

public class User {
    
    
    public String name;
    private String password;

    @JsonIgnore
    public String getPassword() {
    
    
        return password;
    }

    @JsonProperty
    public void setPassword(String password) {
    
    
        this.password = password;
    }

    @Override
    public String toString() {
    
    
        return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}';
    }
}
ObjectMapper mapper = new ObjectMapper();

User userObject = new User();
userObject.setPassword("thePassword");
userObject.setPassword("mingming");

String userAsString = mapper.writeValueAsString(userObject);
System.out.println(userAsString);

String jsonAsString = "{\"name\":\"mingming\",\"password\":\"thePassword\"}";
User userObject1 = mapper.readValue(jsonAsString, User.class);
System.out.println(userObject1);

结果:
{
    
    "name":null}
User{
    
    name='mingming', password='thePassword'}

-------------------------------------------------- --------------------------- Reading notes are excerpted from the article: Jackson – Decide What Fields Get Serialized/Deserialized

Guess you like

Origin blog.csdn.net/weixin_37646636/article/details/132101806