Spring Boot: no String-argument constructor/factory method to deserialize from String value

18,588

Your code works for me. What is the version of spring-boot your are using? do you manage yourself jackson's version ? if so what version is it your are using. Are you sure that the response you get from the external url you are calling is what you pasted in the question ? Here is the working code i copied :

@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;
    }
}
Share:
18,588
dbeja
Author by

dbeja

Updated on June 14, 2022

Comments

  • dbeja
    dbeja almost 2 years

    I'm trying to read a response from a rest service with 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 errors array is present on 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] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not construct instance of co.easymatch.portals.rightmove.entities.RMError: no String-argument constructor/factory method to deserialize from String value ('MND_00026') at [Source: java.io.PushbackInputStream@77f5bb5f; line: 1, column: 532] (through reference chain: co.portals.entities.RMSendPropertyResponse["errors"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of co.portals.entities.RMError: no String-argument constructor/factory method to deserialize from String value ('MND_00026') at [Source: java.io.PushbackInputStream@77f5bb5f; line: 1, column: 532] (through reference chain: co.portals.entities.RMSendPropertyResponse["errors"]->java.util.ArrayList[0])

    And my classes are...

    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 can't understand why there isn't a constructor/factory method to deserialize from String value.

    Thanks