Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a field to custom deserializer class Jackson

I have written a custom deserializer to map only the required fields using jackson. Here goes.

public class GeneralDeserializer extends JsonDeserializer<GeneralDomain> {

    @Override
    public GeneralDomain deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        final JsonNode jsonNode = jp.getCodec().readTree(jp);
        final Map<String, String> map = new ObjectMapper().convertValue(jsonNode, Map.class);
        final String event = "Proxy";
        return new GeneralDomain(map.get("id"), event, map.get("name"), map.get("lastLogin"));
    }

    @Override
    public Class<GeneralDomain> handledType() {
        return GeneralDomain.class;
    }
}

I have a mixin class too for this to add extra annotations.

@JsonDeserialize(using = GeneralDeserializer.class)
public class GeneralDomainMixIn{}

I fetch the object in this way,

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(GeneralDomain.class, SimpleRevealPublicEventMixIn.class);
String json = "{\"id\": 111, \"name\": David, \"lastLogin\": \"02-10-2016 10:32:00 AM\"}";
GeneralDomain readValue = mapper.readValue(json, GeneralDomain.class);

This works great. But as you can see in the custom deserializer, I am hard coding the event field value. This will be passed on by some other instance variable in the main class. I have to pass this field to the custom deserializer. So is there a way to access this variable inside the deserializer? Or is there any other alternative way to achieve this? Please help me out. Thanks.

like image 601
15R6 Avatar asked Oct 14 '16 18:10

15R6


People also ask

How to create a custom deserializer in Jackson?

Jackson Custom Deserializer 1 Create a Class extending StdDeserializer#N#StdDeserializer is the base class to create common deserializers. To create... 2 Register Custom Deserializer with ObjectMapper#N#To register custom deserializer with ObjectMapper, Jackson provides... 3 Register Custom Deserializer with @JsonDeserialize More ...

How do I register a deserializer in JSON?

Register Custom Deserializer with @JsonDeserialize We can register custom deserializer using @JsonDeserialize annotation by attaching to "setter" methods or fields, or to value classes. It has attributes such as using, as, keyAs, contentAs etc. using attribute specifies the custom deserializer class.

How to do custom deserialization of a class in Java?

For custom deserialization, we need to do following below steps. 1. Create a class extending StdDeserializer and then override its deserialize () method.

Why does @jsontypeinfo process before choosing which deserializer to use?

Jackson processes @JsonTypeInfo before choosing which Deserializer to use, probably because the choice of Deserializer could depend generally on the type. However, you can easily disable this on a per-field basis the same way you specify custom Deserializer - by annotating the field directly:


1 Answers

Got the answer finally. Thanks to Philip in this link.

All I had to do was this.

Create an instance of InjectableValues

private InjectableValues injectEventType() {
  return new InjectableValues.Std()
    .addValue("event", "proxy")
}

use this method to set the injectEventType method in mapper class

GeneralDomain readValue = mapper.setInjectableValues(injectEventType()).readValue(json, GeneralDomain.class);

In my deserialize method I had to retrieve the values provided by the InjectableValues:

String event = String.valueOf(ctxt.findInjectableValue("event", null, null));
like image 103
15R6 Avatar answered Sep 19 '22 18:09

15R6