Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass constructor's parameters with jackson?

i am trying to desearlize an object using Jackson

this.prepareCustomMapper().readValue(response.getBody(), EmailResponse.class);

and i have this exception:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.despegar.social.automation.services.emailservice.response.EmailResponse]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.StringReader@4f38f663; line: 1, column: 12] (through reference chain: com.despegar.social.automation.services.emailservice.response.EmailsResponse["items"])
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:746)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:683)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)

I know that this is happening because this is my constructor:

public class EmailResponse extends MyServiceResponse {

    private String id;
    private String user_id;
    private String email;
    private Boolean is_primary;
    private Boolean is_confirmed;

    public EmailResponse(HttpResponse request) {
        super(request);
    }
}

So, my constructor recieve HttpResponse parameter and i am not passing it, but i don't know how to do it. I cant overcharge with an empty constructor because i need that to recieve HttpResponse object at this way. Is there any way to pass this constructor param when i call readValue() method? Or what could be the best option at this case? I appreciate your help. Regards

like image 460
jscherman Avatar asked Dec 05 '25 12:12

jscherman


1 Answers

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}
like image 99
Alexey Gavrilov Avatar answered Dec 07 '25 04:12

Alexey Gavrilov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!