Reputation: 45
I have a nested json pojo where the nested part of json is tagged with @JsonRawValue
. I am trying it to map with rest template, but I am getting the error
JSON parse error: Cannot deserialize instance of java.lang.String out of START_OBJECT token;
The nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException
.
This is what my response object looks like:
import com.fasterxml.jackson.annotation.JsonRawValue;
public class ResponseDTO {
private String Id;
private String text;
@JsonRawValue
private String explanation;
//getters and setters;
}
where explanation
is a json mapped to a string. This works fine with postman, swagger, and I see the explanation as json in the response.
But when I am testing it using Rest Template:
ResponseEntity<ResponseDTO> resonseEntity = restTemplate.exchange(URI, HttpMethod.POST, requestEntity, ResponseDTO.class);
I see this exception:
org.springframework.web.client.RestClientException: Error while extracting
response for type [class com.**.ResponseDTO] and content type
[application/json;charset=utf-8]; nested exception is
org.springframework.http.converter.HttpMessageNotReadableException: JSON
parse error: Cannot deserialize instance of java.lang.String out of
START_OBJECT token; nested exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
deserialize instance of java.lang.String out of START_OBJECT token
at [Source: (PushbackInputStream); line: 1, column: 604] (through
reference chain: com.****.ResponseDTO["explanation"])
Upvotes: 3
Views: 3337
Reputation: 521
Jackson is telling you that it can't insert an Object (in the error log) inside a String.
The @JsonRawValue
is used during serialization of objects to JSON format. It is a way to indicate that the String field is to be sent as-is. In other words, the purpose is to tell Jackson that the String is a valid JSON and should be sent without escaping or quoting.
What you can do instead is provide Jackson with a custom method for it to set the field value. Using JsonNode
as the argument will force Jackson to pass the "raw" value. From there you can get the string representation:
public class ResponseDTO {
private String Id;
private String text;
private String explanation;
//getters and setters;
@JsonProperty("explanation")
private void unpackExplanation(JsonNode explanation) {
this.explanation = explanation.toString();
}
}
Upvotes: 9