Spring Boot: No constructor / factory constructor to deserialize from String value

I'm trying to read the response of a rest service using RestTemplate (Spring Boot):

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<RMSendPropertyResponse> response = restTemplate.exchange("https://url", HttpMethod.POST, entity, RMSendPropertyResponse.class);
RMSendPropertyResponse rmResponse = response.getBody();

      

But when there is an array of errors in the response:

{
    "message": "Something failed.",
    "success": false,
    "errors": [
        {
            "error_code": "MND_00026",
            "error_value": "",
            "error_description": "field not present"
        },
        {
            "error_code": "VAL_00039",
            "error_value": "0",
            "error_description": "Wrong field"
        }
    ],
    "warnings": null,
    "request_timestamp": "18-07-2017 11:34:46",
    "response_timestamp": "18-07-2017 11:34:46"
}

      

I always get this error:

2017-07-18 12: 29: 08.220 WARN 9489 --- [nio-8080-exec-9] .wsmsDefaultHandlerExceptionResolver: Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Failed to read document: Could not create instance co.easymatch.portals.rightmove.entities.RMError: no String-argument constructor / factory to deserialize from String value ('MND_00026') to [Source: java.io.PushbackInputStream@77f5bb5f; line: 1, column: 532] (via reference chain: co.portals.entities.RMSendPropertyResponse ["errors"] → java.util.ArrayList [0]); nested exception com.fasterxml.jackson.databind.JsonMappingException: Unable to instantiate co.portals.entities.RMError: no String-argument constructor / factory to deserialize from String ('MND_00026') value in [Source: java.io.PushbackInputStream @ 77f5bb5f ; line: 1, column: 532] (via reference chain: co.portals.entities.RMSendPropertyResponse ["errors"] -> java.util.ArrayList [0])

And my classes ...

RMSendPropertyResponse class:

@JsonIgnoreProperties(ignoreUnknown = true)
public class RMSendPropertyResponse extends RMResponse {
    private RMPropertyResponse property;
    private List<RMWarning> warnings;
    private List<RMError> errors;

    public RMSendPropertyResponse() {
    }

    public RMPropertyResponse getProperty() {
        return property;
    }

    public void setProperty(RMPropertyResponse property) {
        this.property = property;
    }

    public List<RMWarning> getWarnings() {
        return warnings;
    }

    public void setWarnings(List<RMWarning> warnings) {
        this.warnings = warnings;
    }

    public List<RMError> getErrors() {
        return errors;
    }

    public void setErrors(List<RMError> errors) {
        this.errors = errors;
    }
}

      

RMError class:

@JsonIgnoreProperties(ignoreUnknown = true)
public class RMError {
    private String error_code;
    private String error_description;
    private String error_value;

    public RMError() {
    }

    public String getError_code() {
        return error_code;
    }

    public void setError_code(String error_code) {
        this.error_code = error_code;
    }

    public String getError_description() {
        return error_description;
    }

    public void setError_description(String error_description) {
        this.error_description = error_description;
    }

    public String getError_value() {
        return error_value;
    }

    public void setError_value(String error_value) {
        this.error_value = error_value;
    }
}

      

I don't understand why there is no constructor / factory method to deserialize from a String value.

thank

+3


source to share


1 answer


Your code works for me. What is the version spring-boot

you are using? do you control your jackson

version? if so, which version are you using. Are you sure that the answer you are getting from the external url you are calling is what you pasted into the question? Here is the copied working code:



@RestController
public class MyController {  

 @GetMapping(value = "/read", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity read() {
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<RMSendPropertyResponse> response = restTemplate.exchange("http://localhost:8080/", HttpMethod.GET, null, RMSendPropertyResponse.class);
    RMSendPropertyResponse rmResponse = response.getBody();
    return new ResponseEntity<>(rmResponse, HttpStatus.CREATED);

}

@GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public String get() {
    return "{\n" +
            "    \"message\": \"Something failed.\",\n" +
            "    \"success\": false,\n" +
            "    \"errors\": [\n" +
            "        {\n" +
            "            \"error_code\": \"MND_00026\",\n" +
            "            \"error_value\": \"\",\n" +
            "            \"error_description\": \"field not present\"\n" +
            "        },\n" +
            "        {\n" +
            "            \"error_code\": \"VAL_00039\",\n" +
            "            \"error_value\": \"0\",\n" +
            "            \"error_description\": \"Wrong field\"\n" +
            "        }\n" +
            "    ],\n" +
            "    \"warnings\": null,\n" +
            "    \"request_timestamp\": \"18-07-2017 11:34:46\",\n" +
            "    \"response_timestamp\": \"18-07-2017 11:34:46\"\n" +
            "}";
  }

}

@JsonIgnoreProperties(ignoreUnknown = true)
class RMError {
    private String error_code;
    private String error_description;
    private String error_value;

    public RMError() {
    }

    public String getError_code() {
        return error_code;
    }

    public void setError_code(String error_code) {
        this.error_code = error_code;
    }

    public String getError_description() {
        return error_description;
    }

    public void setError_description(String error_description) {
        this.error_description = error_description;
    }

    public String getError_value() {
        return error_value;
    }

    public void setError_value(String error_value) {
        this.error_value = error_value;
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
class RMSendPropertyResponse {

    private List<RMError> errors;

    public RMSendPropertyResponse() {
    }

    public List<RMError> getErrors() {
        return errors;
    }

    public void setErrors(List<RMError> errors) {
        this.errors = errors;
    }
}

      

+1


source







All Articles