15R6
15R6

Reputation: 307

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.

Upvotes: 9

Views: 7161

Answers (1)

15R6
15R6

Reputation: 307

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));

Upvotes: 7

Related Questions