Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
607 views
in Technique[技术] by (71.8m points)

java - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...