2

I have been struggling with this issue for a couple days now.

Let's say my json response is:

{
"ignoreMe": -1,
"ignoreMeToo": "Not interested in this",
"valuableInfo": [{
        "Info1": {
            "key1": 0.0537,
            "key2": 0.0759
        }
    }, {
        "Info2": {
            "key2": 0.0444,
            "key4": 0.2345
        }
    }
]}

From this response i want to be able to map to my custom pojo object, which should look like this;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseDTO{
   private List<Map<String, Double>> valuableInfo;

    public ResponseDTO(List<Map<String, Double>> valuableInfo) {
        this.valuableInfo = valuableInfo;
    }

    public List<Map<String, Double>> getvaluableInfo() {
        return valuableInfo;
    }

    public void setvaluableInfo(List<Map<String, Double>> valuableInfo) {
        this.valuableInfo = valuableInfo;
    }
}

How do i setup my mapper to perform this conversion using just;

mapper.readValue(jsonResponse, ResponseDTO.class)
3
  • You need to have a public constructor for the class with out parameter. Commented Jul 27, 2018 at 11:09
  • is "Info1" has list of elements? Means, "Info1" [ {} ] or its a just "Info1" {} Commented Jul 27, 2018 at 11:16
  • @ShaunakPatel no it is just info1{} Commented Jul 27, 2018 at 12:07

2 Answers 2

5

I guess your error is, that Jackson can't find a suitable no-arg constructor for ResponseDTO (because there is none). To overcome this you can work with the @JsonCreator and @JsonProperty annotations. See the changed constructor:

@JsonCreator
public ResponseDTO(@JsonProperty("valuableInfo") List<Map<String, Double>> valuableInfo){
    this.valuableInfo = valuableInfo;
}

The rest of the code can stay the same.

This just tells jackson that it should inject the property with name "valuableInfo" into that constructor.

Sign up to request clarification or add additional context in comments.

5 Comments

Nice answer. It is a pity that Java doesn't ease the retrieval of the parameter names by reflection (as it requires the debug option enabled). It would avoid the @JsonProperty("valuableInfo") declaration both verbose and not good for the maintenance.
@davidxxx It has been bothering me many times that it's not possible, but that's just how java is. It would probably be even better to not write such code yourself, but let it generate with Swagger or something, which would almost eliminate the case of maintenance problems.
Thank you for your suggestion, after making the changes you suggested, i get this error; "com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.Double out of START_OBJECT token" i think it might have something to do with the Map<String, Double>
@waqask87 after looking at your question It is clear why that is. The valuableInfo contains a List of objects, with one property, which then contains a map. [{ "Info1":{"key1": 0.0537}}] So you'd need a List<Map<String, Map<String, Double>>> which makes me want to vomit. So instead, create new POJO instead using maps
Is there no way i could bypass this interim object? @Lino
0

Observe carefully your json. Here valuableInfo contains List of objects. And every object contains Map< String,Object >. Then you class need to be like:

@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseDTO{
private List<Map<String, Map<String, Double>>> valueableInfo;

@JsonCreator
public ResponseDTO(@JsonProperty("valuableInfo") List<Map<String, Map<String, Double>>> valuableInfo){
    this.valueableInfo = valuableInfo;
}

public List<Map<String, Map<String, Double>>> getValueableInfo() {
    return valueableInfo;
}

public void setValueableInfo(List<Map<String, Map<String, Double>>> valueableInfo) {
    this.valueableInfo = valueableInfo;
}
}

2 Comments

Is there no way around that issue? i really just want a List<String, Map<String, Double>>
then need to change in your json

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.