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!