Class JacksonDeserializerFactory

java.lang.Object
io.quarkus.resteasy.reactive.jackson.deployment.processor.JacksonCodeGenerator
io.quarkus.resteasy.reactive.jackson.deployment.processor.JacksonDeserializerFactory

public class JacksonDeserializerFactory extends JacksonCodeGenerator
Generates an implementation of the Jackson's StdDeserializer for each class that needs to be deserialized from json. In this way the deserialization process can be performed through the ad-hoc generate deserializer and then without any use of reflection. For instance for a pojo like this

 public class Person {
     private String firstName;

     @JsonProperty("familyName")
     private String lastName;

     private int age;

     @SecureField(rolesAllowed = "admin")
     private Address address;

     public Person() {
     }

     public Person(String firstName, String lastName, int age, Address address) {
         this.firstName = firstName;
         this.lastName = lastName;
         this.age = age;
         this.address = address;
     }

     // getters and setters omitted
 }
 
it generates the following StdDeserializer implementation

 public class Person$quarkusjacksondeserializer extends StdDeserializer {
     public Person$quarkusjacksondeserializer() {
         super(Person.class);
     }

     public Object deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JacksonException {
         Person person = new Person();
         Iterator iterator = ((JsonNode) jsonParser.getCodec().readTree(jsonParser)).fields();

         while (iterator.hasNext()) {
             Map.Entry entry = (Map.iterator) var3.next();
             String field = (String) entry.getKey();
             JsonNode jsonNode = (JsonNode) entry.getValue();
             switch (field) {
                 case "firstName":
                     person.setFirstName(jsonNode.asText());
                     break;
                 case "familyName":
                     person.setLastName(jsonNode.asText());
                     break;
                 case "age":
                     person.setAge(jsonNode.asInt());
                     break;
                 case "address":
                     person.setAddress(context.readTreeAsValue(jsonNode, Address.class));
                     break;
             }
         }

         return person;
     }
 }
 
Note that in this case also the Address class has to be deserialized in the same way, and then this factory triggers the generation of a second StdDeserializer also for it. More in general if during the generation of a deserializer for a given class it discovers a non-primitive field of another type for which a deserializer hasn't been generated yet, this factory enqueues a code generation also for that type. The same is valid for both arrays of that type, like Address[], and collections, like List<Address&gt. Also note that this works only if the Java class to be deserialized has an empty constructor, while the generation of this deserializer is skipped in all other cases. In particular this cannot work with records. If the class to be deserialized has one or more generics parameter, the generated deserializer also implements the ContextualDeserializer interface. For instance for a class like the following

 public class DataItem<T> {

     private T content;

     public T getContent() {
         return content;
     }

     public void setContent(T content) {
         this.content = content;
     }
 }
 
the corresponding generated deserializer will be

 public class DataItem$quarkusjacksondeserializer extends StdDeserializer implements ContextualDeserializer {
     private JavaType[] valueTypesmvn clean install;

     public DataItem$quarkusjacksondeserializer() {
         super(DataItem.class);
     }

     public Object deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JacksonException {
         DataItem dataItem = new DataItem();
         Iterator iterator = ((JsonNode) jsonParser.getCodec().readTree(jsonParser)).fields();

         while (iterator.hasNext()) {
             Map.Entry entry = (Map.iterator) var3.next();
             String field = (String) entry.getKey();
             JsonNode jsonNode = (JsonNode) entry.getValue();
             if (jsonNode.isNull()) {
                 continue;
             }
             switch (field) {
                 case "content":
                     dataItem.setContent(context.readTreeAsValue(jsonNode, this.valueTypes[0]));
                     break;
             }
         }

         return dataItem;
     }

     public JsonDeserializer createContextual(DeserializationContext context, BeanProperty beanProperty) {
         JavaType[] valueTypes = JacksonMapperUtil.getGenericsJavaTypes(context, beanProperty);
         DataItem$quarkusjacksondeserializer deserializer = new DataItem$quarkusjacksondeserializer();
         deserializer.valueTypes = valueTypes;
         return (JsonDeserializer) deserializer;
     }
 }
 
  • Constructor Details

    • JacksonDeserializerFactory

      public JacksonDeserializerFactory(io.quarkus.deployment.annotations.BuildProducer<io.quarkus.deployment.builditem.GeneratedClassBuildItem> generatedClassBuildItemBuildProducer, org.jboss.jandex.IndexView jandexIndex)
  • Method Details