i am trying to desearlize an object using Jackson
this.prepareCustomMapper().readValue(response.getBody(), EmailResponse.class);
and i have
You can write your custom deserializer: http://jackson.codehaus.org/1.5.7/javadoc/org/codehaus/jackson/map/annotate/JsonDeserialize.html
In that case you will be able to pass any values that you want into the constructor. You will need to add @JsonDeserialize annotation on EmailResponse like:
@JsonDeserialize(using = EmailResponseDeserializer.class)
Deserializer implementation example:
public class EmailResponseDeserializer extends JsonDeserializer<EmailResponse> {
HttpResponse httpResponse;
public EmailResponceDeserializer(HttpResponse httpResponse) {
this.httpResponse = httpResponse;
}
@Override
public EmailResponse deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
int id = (Integer) ((IntNode) node.get("id")).numberValue();
String email = node.get("email").asText();
EmailResponse emailResponse = new EmailResponse(httpResponse)
emailResponse.setId(id);
emailResponse.setEmail(email);
// other properties
return emailResponse;
}
}
Also you will need to register the custom deserializer:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(EmailResponse.class, new EmailResponseDeserializer(httpRespose));
mapper.registerModule(module);
Generally, I would say that by adding HttpResponse into EmailRespose bean you are adding some implementation into the DTO object which shouldn't have any. I don't think that this is a good idea to set httpResponse into the custom deserialiser and then set it into the EmailResponse but nothing prevent you of doing it.
Hope this helps.
You can use the Jackson value injection feature to pass an object reference which is not a part of the input JSON as a constructor parameter. Here is an example:
public class JacksonInjectExample {
private static final String JSON = "{\"field1\":\"value1\", \"field2\":123}";
// HttpResponse in your case
public static class ExternalObject {
@Override
public String toString() {
return "MyExternalObject";
}
}
public static class Bean {
// make fields public to avoid writing getters in this example
public String field1;
public int field2;
private ExternalObject external;
public Bean(@JacksonInject final ExternalObject external) {
this.external = external;
}
@Override
public String toString() {
return "Bean{" +
"field1='" + field1 + '\'' +
", field2=" + field2 +
", external=" + external +
'}';
}
}
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
final InjectableValues.Std injectableValues = new InjectableValues.Std();
injectableValues.addValue(ExternalObject.class, new ExternalObject());
mapper.setInjectableValues(injectableValues);
final Bean bean = mapper.readValue(JSON, Bean.class);
System.out.println(bean);
}
}
Output:
Bean{field1='value1', field2=123, external=MyExternalObject}