Jackson’s common notes

Serialized annotations

@JsonAnyGetter

Serialize the Map like a normal property

public class ExtendableBean {
    public String name;
    private Map<String, String> properties;
 
    @JsonAnyGetter
    public Map<String, String> getProperties(a) {
        returnproperties; }}Copy the code

Serialization example:

{
    "name":"My bean"."attr2":"val2"."attr1":"val1"
}
Copy the code

@JsonGetter

Marks the specified method as a getter method. Can be used instead of @jsonProperty

public class MyBean {
    public int id;
    private String name;
 
    @JsonGetter("name")
    public String getTheName(a) {
        returnname; }}Copy the code

Serialization example:

{
    "id": 1."name":"My bean"
}
Copy the code

@JsonPropertyOrder

Used on classes to customize the output order of attributes during serialization

@JsonPropertyOrder({ "name", "id" })
public class MyBean {
    public int id;
    public String name;
}
Copy the code

Serialization example:

{
    "name":"My bean"."id": 1
}
Copy the code

@JsonRawValue

Serialize the value of the attribute exactly as-is

public class RawBean {
    public String name;
 
    @JsonRawValue
    public String json;
}
Copy the code

Such as:

RawBean bean = new RawBean("My bean"."{\"attr\":false}");
Copy the code

Serialize to:

{
    "name":"My bean"."json": {"attr":false}}Copy the code

Instead of:

{
    "name":"My bean"."json":"{\"attr\":false}"
}
Copy the code

@JsonValue

Define a serialization method for the entire entity, the output of which Jackson will use as the serialization output.

public enum TypeEnumWithValue {
    TYPE1(1."Type A"), TYPE2(2."Type 2");
 
    private Integer id;
    private String name;
 
    // standard constructors
 
    @JsonValue
    public String getName(a) {
        returnname; }}Copy the code

Serialization example:

{
  "name": "Type 2"
}
Copy the code

@JsonRootName

If you need to wrap an entity one layer, you can specify the name of the root wrapper using @jsonRootName

@JsonRootName(value = "user")
public class UserWithRoot {
    public int id;
    public String name;
}
Copy the code

Serialization example:

{
    "user": {
        "id": 1."name": "John"}}Copy the code

If this annotation is not used, it will be serialized to:

{
    "id": 1."name": "John"
}
Copy the code

@JsonSerialize

Used to specify a custom serializer to serialize entities

public class Event {
    public String name;
 
    @JsonSerialize(using = CustomDateSerializer.class)
    public Date eventDate;
}
Copy the code

Custom serializers are as follows:

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

Example output:

{
  "name": "test"."eventDate": "The 20-12-2014 02:30:00"
}
Copy the code

Deserialized annotations

@JsonCreator

Specifies the constructor or method to use for deserialization

Example Json to be deserialized:

{
    "id":1."theName":"My bean"
}
Copy the code
public class BeanWithCreator {
    public int id;
    public String name;
 
    @JsonCreator
    public BeanWithCreator(@JsonProperty("id") int id, @JsonProperty("theName") String name) {
        this.id = id;
        this.name = name; }}Copy the code

@JacksonInject

Specify that a field is assigned from injection, not from Json

public class BeanWithInject {
    @JacksonInject
    public int id;
     
    public String name;
}
Copy the code

Example usage:

String json = "{\"name\":\"My bean\"}";
 
InjectableValues inject = new InjectableValues.Std()
  .addValue(int.class, 1);
BeanWithInject bean = new ObjectMapper().reader(inject)
  .forType(BeanWithInject.class)
  .readValue(json);
Copy the code

@JsonAnySetter

Treat Map as a normal property when deserializing

Json to deserialize:

{
    "name":"My bean"."attr2":"val2"."attr1":"val1"
}
Copy the code
public class ExtendableBean {
    public String name;
    private Map<String, String> properties;
 
    @JsonAnySetter
    public void add(String key, String value) { properties.put(key, value); }}Copy the code

The value of the properties field will be attr2 -> val2 and attr1 -> val1 key-value pairs.

@JsonSetter

Mark the method as a setter method, and you can specify the property name

public class MyBean {
    public int id;
    private String name;
 
    @JsonSetter("name")
    public void setTheName(String name) {
        this.name = name; }}Copy the code

@JsonDeserialize

Used to specify a custom deserializer to deserialize entities

public class Event {
    public String name;
 
    @JsonDeserialize(using = CustomDateDeserializer.class)
    public Date eventDate;
}
Copy the code

The corresponding deserializer:

public class CustomDateDeserializer
  extends StdDeserializer<Date> {
 
    private static SimpleDateFormat formatter
      = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
 
    public CustomDateDeserializer(a) { 
        this(null); 
    } 
 
    public CustomDateDeserializer(Class
        vc) { 
        super(vc); 
    }
 
    @Override
    public Date deserialize( JsonParser jsonparser, DeserializationContext context) 
      throws IOException {
         
        String date = jsonparser.getText();
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            throw newRuntimeException(e); }}}Copy the code

Jackson sets whether the property participates in serialization

@JsonIgnoreProperties

Specify attributes on the class to ignore

@JsonIgnoreProperties({ "id" })
public class BeanWithIgnore {
    public int id;
    public String name;
}
Copy the code

@JsonIgnore

Ignore specific attributes so they do not participate in the serialization process

public class BeanWithIgnore {
    @JsonIgnore
    public int id;
 
    public String name;
}
Copy the code

Is equivalent to @jsonIgnoreProperties.

@JsonIgnoreType

When applied to a class, all attributes of the class are ignored

public class User {
    public int id;
    public Name name;
 
    @JsonIgnoreType
    public static class Name {
        public String firstName;
        publicString lastName; }}Copy the code

@JsonInclude

Use to exclude attributes with values of empty/null/default

@JsonInclude(Include.NON_NULL)
public class MyBean {
    public int id;
    public String name;
}
Copy the code

@JsonAutoDetect

Force serialization of a private property, regardless of whether it has getter methods

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class PrivateBean {
    private int id;
    private String name;
}
Copy the code

Jackson deals with polymorphism

Generally used in combination, with the following three notes:

  • @JsonTypeInfo

Specifies the details of the type information contained in the serialization

  • @JsonSubTypes

Specifies a subtype of an annotated type

  • @JsonTypeName

Specifies the logical type name for the annotated class

public class Zoo {
    public Animal animal;
 
    @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type")
    @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "dog"), @JsonSubTypes.Type(value = Cat.class, name = "cat") })
    public static class Animal {
        public String name;
    }
 
    @JsonTypeName("dog")
    public static class Dog extends Animal {
        public double barkVolume;
    }
 
    @JsonTypeName("cat")
    public static class Cat extends Animal {
        boolean likesCream;
        public intlives; }}Copy the code

In the example above, the attribute type is specified to determine the specific subclass. For example, type=dog will be serialized to the dog type.

Jackson Universal Annotations (both serialization and deserialization work)

@JsonProperty

Specify the name of the property in JSON

public class MyBean {
    public int id;
    private String name;
 
    @JsonProperty("name")
    public void setTheName(String name) {
        this.name = name;
    }
 
    @JsonProperty("name")
    public String getTheName(a) {
        returnname; }}Copy the code

@JsonFormat

Used to specify the format when serializing date/time values.

public class Event {
    public String name;
 
    @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    public Date eventDate;
}
Copy the code

@JsonUnwrapped

It is not easy to describe, but simply unwrap, all properties of an object to the current level.

public class UnwrappedUser {
    public int id;
 
    @JsonUnwrapped
    public Name name;
 
    public static class Name {
        public String firstName;
        publicString lastName; }}Copy the code

Serialization example:

{
    "id":1."firstName":"John"."lastName":"Doe"
}
Copy the code

If not annotated @jsonunwrapped, it is serialized as:

{
    "id":1."name": {
        "firstName":"John"."lastName":"Doe"}}Copy the code

@JsonView

Specify views, like grouping for serialization/deserialization

Define a view:

public class Views {
    public static class Public {}
    public static class Internal extends Public {}}Copy the code

Define entities:

public class Item {
    @JsonView(Views.Public.class)
    public int id;
 
    @JsonView(Views.Public.class)
    public String itemName;
 
    @JsonView(Views.Internal.class)
    public String ownerName;
}
Copy the code

Serialization example:

String result = new ObjectMapper()
  .writerWithView(Views.Public.class)
  .writeValueAsString(item);
Copy the code

At this point, only the ID and itemName fields will be serialized

@JsonManagedReference, @JsonBackReference

The @JsonManagedReference and @JsonBackReference annotations are used to handle parent/child relationships and solve loop problems.

For example, there are two classes that reference each other:

public class ItemWithRef {
    public int id;
    public String itemName;
 
    @JsonManagedReference
    public UserWithRef owner;
}
Copy the code
public class UserWithRef {
    public int id;
    public String name;
 
    @JsonBackReference
    public List<ItemWithRef> userItems;
}
Copy the code

This can be avoided by using @jsonManagedReference and @jsonBackReference.

@JsonIdentityInfo

Used to specify the use of object identifiers when serializing/deserializing values, for example, when dealing with infinite recursive types.

@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ItemWithIdentity {
    public int id;
    public String itemName;
    public UserWithIdentity owner;
}
Copy the code

@JsonFilter

Specifies the filter to use during serialization.

@JsonFilter("myFilter")
public class BeanWithFilter {
    public int id;
    public String name;
}
Copy the code

Sample code:

BeanWithFilter bean = new BeanWithFilter(1."My bean");

FilterProvider filters 
  = new SimpleFilterProvider().addFilter(
    "myFilter", 
    SimpleBeanPropertyFilter.filterOutAllExcept("name"));

String result = new ObjectMapper()
  .writer(filters)
  .writeValueAsString(bean);
Copy the code

Custom Jackson annotations

Custom annotations can be developed using @JacksonAnnotationsinside

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id", "dateCreated" })
public @interface CustomAnnotation {}
Copy the code

How to use custom annotations:

@CustomAnnotation
public class BeanWithCustomAnnotation {
    public int id;
    public String name;
    public Date dateCreated;
}
Copy the code

Custom annotations enhance code reuse by combining common Jackson annotations into a new annotation that can replace the combined annotations.

Jackson mixins annotation

Dynamically add uniform Jackson annotations for certain types

Entity:

public class Item {
    public int id;
    public String itemName;
    public User owner;
}
Copy the code

A MixIn classes:

@JsonIgnoreType
public class MyMixInForIgnoreType {}
Copy the code

We can dynamically disengage the User type from serialization:

Item item = new Item(1."book".null);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(User.class, MyMixInForIgnoreType.class);
result = mapper.writeValueAsString(item);
Copy the code

Disabling Jackson annotations

Suppose we have an entity with Jackson annotations:

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id" })
public class MyBean {
    public int id;
    public String name;
}
Copy the code

We can disable all Jackson annotations on this entity like this:

MyBean bean = new MyBean(1.null);
ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_ANNOTATIONS);
Copy the code

Jackson’sObjectMapperusage

javaClass is converted tojson

Can be serialized directly to a Json string:

objectMapper.writeValueAsString(car);
Copy the code

Alternatively, it can be serialized to a file containing a Json string:

objectMapper.writeValue(new File("target/car.json"), car);
Copy the code

jsonconvertjavaclass

From the string:

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
objectMapper.readValue(json, Car.class); 
Copy the code

From the file:

objectMapper.readValue(new File("target/json_car.json"), Car.class);
Copy the code

From the URL:

objectMapper.readValue(new URL("target/json_car.json"), Car.class);
Copy the code

jsonconvertJackson JsonNode

String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }";
JsonNode jsonNode = objectMapper.readTree(json);
String color = jsonNode.get("color").asText();
// Output: color -> Black
Copy the code

jsonconvertjavaA collection of

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});
Copy the code

jsonconvertMap

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Map<String, Object> map = objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){});
Copy the code

ObjectMapperCommon configuration of

Ignore other fields (json attributes differ from the target entity attributes) :

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Copy the code

Original value null is allowed:

objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
Copy the code

Allows serialization/deserialization of enumerations to numbers:

objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);
Copy the code

Configure custom serializers/deserializers

Suppose we have a serializer:

public class CustomCarSerializer extends StdSerializer<Car> {
     
    public CustomCarSerializer(a) {
        this(null);
    }
 
    public CustomCarSerializer(Class<Car> t) {
        super(t);
    }
 
    @Override
    public void serialize( Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("car_brand", car.getType()); jsonGenerator.writeEndObject(); }}Copy the code

A deserializer:

public class CustomCarDeserializer extends StdDeserializer<Car> {
     
    public CustomCarDeserializer(a) {
        this(null);
    }
 
    public CustomCarDeserializer(Class
        vc) {
        super(vc);
    }
 
    @Override
    public Car deserialize(JsonParser parser, DeserializationContext deserializer) {
        Car car = new Car();
        ObjectCodec codec = parser.getCodec();
        JsonNode node = codec.readTree(parser);
         
        // try catch block
        JsonNode colorNode = node.get("color");
        String color = colorNode.asText();
        car.setColor(color);
        returncar; }}Copy the code

Use them with ObjectMapper:

// Add a custom serializer
module.addSerializer(Car.class, new CustomCarSerializer());
// Add a custom deserializer
module.addDeserializer(Car.class, new CustomCarDeserializer());
Copy the code

Dealing with date formatting

ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
objectMapper.setDateFormat(df);
Copy the code

Handle collection

Deserialize to an array:

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);
Copy the code

Deserialize to a collection:

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});
Copy the code

ObjectMapperBasic usage of

ObjectMapperCan be achieved byconfigureMethod to set the global serialization/deserialization behavior, for example:

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Copy the code

Some common Settings:

  1. DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES: Ignores other fields
  2. DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES: allows deserialization using the default values of attributes
  3. DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS: allows serialization/deserialization of enumerated values to numbers

Register custom serializers/deserializers

// Create a module
SimpleModule module = new SimpleModule("CustomCarSerializer".new Version(1.0.0.null.null.null));
// Register custom serializers/deserializers with the module
module.addSerializer(Car.class, new CustomCarSerializer());
//module.addDeserializer(Car.class, new CustomCarDeserializer());
// Register module
mapper.registerModule(module);
Copy the code

Processing date format

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
mapper.setDateFormat(df);
Copy the code

Handle collection

Handle arrays

String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);
Copy the code

Handle collection

String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});
Copy the code

Jackson Annotation Extension

@JsonIdentityReference

Serialize a Java object using the specified identity instead of serializing the entire object

Such as:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
public class BeanWithoutIdentityReference {
    private int id;
    private String name;
}
Copy the code

Will be serialized to:

1
Copy the code

@JsonAppend

The runtime adds additional attributes at serialization time

@JsonAppend(attrs = { @JsonAppend.Attr(value = "version") })
public class BeanWithAppend {
    private int id;
    private String name;
 
    // constructor, getters and setters
}
Copy the code

For example, we manually added the version = 1.0 attribute at serialization time

BeanWithAppend bean = new BeanWithAppend(2."Bean With Append Annotation");
ObjectWriter writer = mapper.writerFor(BeanWithAppend.class).withAttribute("version"."1.0");
String jsonString = writer.writeValueAsString(bean);
Copy the code

Serialization results:

{
    "id": 2."name": "Bean With Append Annotation"."version": "1.0"
}
Copy the code

@JsonNaming

Specifies how properties are named when serialized

There are four options:

  • KEBAB_CASE

The value is separated by a hyphen, for example, kebab-case

  • LOWER_CASE

All letters are lowercase, such as lowercase

  • SNAKE_CASE

All letters are converted to lowercase and separated by underscores, such as snake_case

  • UPPER_CAMEL_CASE

All name elements, including the first, begin with a capital letter followed by a lowercase letter, and have no delimiter, for example, UpperCamelCase

Examples:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class NamingBean {
    private int id;
    private String beanName;
}
Copy the code

@JsonPropertyDescription

Description of a field

For example, have the following entity:

public class PropertyDescriptionBean {
    private int id;
    @JsonPropertyDescription("This is a description of the name property")
    private String name;
}
Copy the code

We can print information about this class:

SchemaFactoryWrapper wrapper = new SchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(PropertyDescriptionBean.class, wrapper);
JsonSchema jsonSchema = wrapper.finalSchema();
String jsonString = mapper.writeValueAsString(jsonSchema);
Copy the code

The results are as follows:

{
    "type": "object"."id": "urn:jsonschema:com:baeldung:jackson:annotation:extra:PropertyDescriptionBean"."properties": 
    {
        "name": 
        {
            "type": "string"."description": "This is a description of the name property"
        },
 
        "id": 
        {
            "type": "integer"}}}Copy the code

@JsonPOJOBuilder

Custom generator classes to control the deserialization behavior of JSON

The @jsonPojoBuilder has two properties

  • buildMethodName

The name used to instantiate the no-parameter construction of the expected bean after binding the JSON field to the bean’s properties. The default name is Build.

  • withPrefix

A name prefix used to automatically detect matches between JSON and bean properties. The default prefix is with.

Suppose we want to deserialize json as follows

{
    "id": 5."name": "POJO Builder Bean"
}
Copy the code

Corresponding POJOs:

@JsonDeserialize(builder = BeanBuilder.class)
public class POJOBuilderBean {
    private int identity;
    private String beanName;
 
    // constructor, getters and setters
}
Copy the code

Corresponding generator:

@JsonPOJOBuilder(buildMethodName = "createBean", withPrefix = "construct")
public class BeanBuilder {
    private int idValue;
    private String nameValue;
 
    public BeanBuilder constructId(int id) {
        idValue = id;
        return this;
    }
 
    public BeanBuilder constructName(String name) {
        nameValue = name;
        return this;
    }
 
    public POJOBuilderBean createBean(a) {
        return newPOJOBuilderBean(idValue, nameValue); }}Copy the code

Deserialize with ObjectMapper:

String jsonString = "{\"id\":5,\"name\":\"POJO Builder Bean\"}";
POJOBuilderBean bean = mapper.readValue(jsonString, POJOBuilderBean.class);
Copy the code

conclusion

Although most of the above features are not used in our jobs, as educated programmers, it never hurts to know a little more about them!

If this blog has been helpful to you, please leave a comment + like + favorites.

I am A Chen, on the road of technology we strive to move forward together!