没有字符串参数的构造函数/工厂方法可以从字符串值反序列化 - 从restTemplate反序列化json对象时出现异常

15

在尝试调用并解析JSON响应时,遇到了问题。

[
    {
        "name": "john doe",
        "age": "24",
        "address": "{\"state\":\"LA\",\"country\":\"US\"}"
    }
]

Models:

Person.java

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true) 
public class Person {
    private String name;
    private String age;
    private Address address;
}

地址.java

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true) 
public class Address {
    private String state;
    private String country;
}

代码读取这些数据:

ResponseEntity<List<Person>> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET,requestEntity,new ParameterizedTypeReference<List<Person>>() {});

但是我收到以下异常:

调用ABS服务时出现RestClientException错误,提取类型为[java.util.List<com.bp.model.Person>]和内容类型[application/json;charset=UTF-8]的响应时发生ServiceError;嵌套异常为org.springframework.http.converter.HttpMessageNotReadableException:JSON解析错误:无法构造com.bp.model.Address实例(尽管至少存在一个创建者):没有String参数构造函数/工厂方法从字符串值('{"state":"LA","country":"US"}')反序列化;嵌套异常为com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造com.bp.model.Address实例(尽管至少存在一个创建者):没有String参数构造函数/工厂方法从字符串值('{"state":"IN","brand":"anthem"}')反序列化 在[来源:(PushbackInputStream);行:1,列:325](通过引用链:java.util.ArrayList [0] -> com.bp.model.Person ["address"])


@rph 非常感谢!我完全忽略了 JSON :) - Sriram G
3
你应该将答案标记为已接受。 - user5826312
3个回答

16

代码是正确的,但JSON存在问题。地址是一个字符串而不是JSON对象。为了让它正常工作,需要像这样:

"address": {"state": "LA", "country": "US"}

去除外部引号和转义字符。


这应该是被接受的答案。它也可以接受括号而不是大括号。 - riddle_me_this

1

JSON字符串转Map:
String json = "{"name":"mkyong", "age":"37"}";
输出 {name=mkyong, age=37}

public static void main(String[] args) {
    ObjectMapper mapper = new ObjectMapper();
    String json = "{\"name\":\"mkyong\", \"age\":\"37\"}";
    try {
        // convert JSON string to Map
        Map<String, String> map = mapper.readValue(json, Map.class);

        // it works
        //Map<String, String> map = mapper.readValue(json, new TypeReference<Map<String, String>>() {});
        System.out.println(map);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

将Map转换为JSON字符串:
{"name":"mkyong","age":"37"}
{ "name" : "mkyong", "age" : "37" }

public static void main(String[] args) {
    ObjectMapper mapper = new ObjectMapper();
    Map<String, String> map = new HashMap<>();
    map.put("name", "mkyong");
    map.put("age", "37");
    try {
        // convert map to JSON string
        String json = mapper.writeValueAsString(map);
        System.out.println(json);   // compact-print

        json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
        System.out.println(json);   // pretty-print

    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

在Jackson中,我们可以使用mapper.readValue(json, Map.class)将JSON字符串转换为Map。依赖关系.
<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.8</version>
  </dependency>

0

在这里,我们可以尝试在运行时设置值。

@JsonProperty("address")
    public void setCustomAddress(String addressFromJson){
        this.address = new Gson().fromJson(addressFromJson, Address.class);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接