Home > other >  How to map a JSON string which includes members named long and short
How to map a JSON string which includes members named long and short

Time:05-15

I need to map a JSON string which includes values named long and short:

"status": {
   "long": "Finished",
   "short": "F",
   "elapsed": 90
}

I tried the following class:

public class Status {

    @JsonProperty("long")
    public String _long;
    @JsonProperty("short")
    public String _short;
    @JsonProperty("elapsed")
    public Object elapsed;

}

with the command:

objectMapper.readValue(resBody, Response.class);

response contains the status part:

{
    "response": {
        "id": 157016,
        "timezone": "UTC",
        "date": "2019-08-10T11:30:00 00:00",
        "timestamp": 1565436600,
        "status": {
            "long": "Long Value",
            "short": "LV",
            "elapsed": 20
        }
    }
}

But still I get the following error:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "long"

How can this be fixed? I do not have control on the JSON format.

CodePudding user response:

One of the ways to solve the problem is select the json part you are interested combining the ObjectMapper#readTree method that converts your json to a JsonNode object and then select the part of the JsonNode object you are looking for with the JsonNode#at method which matches the /response/status path expression like below:

//it contains only the status labelled node of your json
JsonNode statusNode = mapper.readTree(json).at("/response/status");   

After you can use the ObjectMapper#convertValue method to convert the JsonNode to your Status class obtaining the expected result:

JsonNode statusNode = mapper.readTree(json).at("/response/status");
Status status = mapper.convertValue(statusNode, Status.class);
//ok, it prints {"long":"Long Value","short":"LV","elapsed":20}
System.out.println(mapper.writeValueAsString(status));

CodePudding user response:

Well, it is obviously not a perfect solution to the problem, but one may find it as a helpfull workaround:

Since I don't care about these values, I'll just rename their names and adapt the class members name accordingly:

on the json string resBody I get as a response I will do the following

@NotNull 
private static String mitigateLongAndShortValueNames(String resBody) { 
   resBody = resBody.replaceAll("\"long\":", "\"longValue\":"); 
   resBody = resBody.replaceAll("\"short\":", "\"shortValue\":"); 
   return resBody; 
} 

and change

public class Status {

    @JsonProperty("long")
    public String _long;
    @JsonProperty("short")
    public String _short;
    @JsonProperty("elapsed")
    public Object elapsed;

}

to

public class Status {

    public String longValue;
    public String shortValue;
    public Object elapsed;

}

It worked for me!

  • Related