Ankit
Ankit

Reputation: 45

Map nested json to a pojo with raw json value

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

Answers (1)

Jo&#227;o Dias Amaro
Jo&#227;o Dias Amaro

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

Related Questions