Spring Boot:没有从字符串值反序列化的字符串参数构造函数/工厂方法

Posted

技术标签:

【中文标题】Spring Boot:没有从字符串值反序列化的字符串参数构造函数/工厂方法【英文标题】:Spring Boot: no String-argument constructor/factory method to deserialize from String value 【发布时间】:2017-12-23 06:31:57 【问题描述】:

我正在尝试使用 RestTemplate (Spring Boot) 读取来自休息服务的响应:

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

但是当响应中出现错误数组时:


    "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"

我总是收到这个错误:

2017-07-18 12:29:08.220 警告 9489 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : 无法读取 HTTP 信息: org.springframework.http.converter.HttpMessageNotReadableException: 无法读取文档:无法构造实例 co.easymatch.portals.rightmove.entities.RMError:没有字符串参数 从字符串值反序列化的构造函数/工厂方法 ('MND_00026') 在 [来源:java.io.PushbackInputStream@77f5bb5f;线: 1、栏目:532](通过引用链: co.portals.entities.RMSendPropertyResponse["errors"]->java.util.ArrayList[0]); 嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:无法构造 co.portals.entities.RMError 的实例:没有字符串参数 从字符串值反序列化的构造函数/工厂方法 ('MND_00026') 在 [来源:java.io.PushbackInputStream@77f5bb5f;线: 1、栏目:532](通过引用链: co.portals.entities.RMSendPropertyResponse["errors"]->java.util.ArrayList[0])

我的课是……

RMSendPropertyResponse 类:

@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 类:

@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;
    

我不明白为什么没有构造函数/工厂方法来反序列化字符串值。

谢谢

【问题讨论】:

【参考方案1】:

您的代码对我有用。 您使用的spring-boot 是什么版本?你自己管理jackson的版本吗?如果是这样,您使用的是什么版本。 您确定从您调用的外部 url 获得的响应是​​您粘贴在问题中的内容吗? 这是我复制的工作代码:

@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;
    

【讨论】:

谢谢!我正在使用 Spring Boot 1.4.2。我不管理杰克逊版本。 Spring Boot 正在获取 Jackson 2.8.4。如果我使用 Postman 调用相同的服务,这就是我得到的原始响应。我会尝试像你一样直接传递这个原始答案,看看我是否仍然遇到同样的错误。 好的,所以我尝试像您一样手动创建响应并且它有效。难道是由于某种原因,我在 Postman 上得到的回应与我在项目中得到的不同?您知道调试来自 RestTemplate 的原始响应的最佳方法吗? 好的,找到问题了...我添加了一个拦截器,当出现错误时,服务默认以xml而不是json回复。我强迫标题只接受 json,现在可以正常工作了! 当我需要调试我正在通过 RestTemplate 进行的交换时,我使用ClientHttpRequestInterceptor 的实现来记录所有请求和响应。很高兴您解决了问题。

以上是关于Spring Boot:没有从字符串值反序列化的字符串参数构造函数/工厂方法的主要内容,如果未能解决你的问题,请参考以下文章

Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)

objectmapper.readValue() 失败并出现错误“没有从字符串值反序列化的字符串参数构造函数/工厂方法”

使用 Jackson 从 XML 到 POJO 的反序列化问题:没有从字符串值反序列化的字符串参数构造函数/工厂方法

即使存在默认构造函数,也无法从 Object 值反序列化(没有基于委托或基于属性的 Creator)

没有像默认构造一样的创建者):不能从对象值反序列化(没有基于委托或属性的创建者

openapi springboot generator jackson no String-argument构造函数/工厂方法从字符串值反序列化