no String-argument constructor/factory method to deserialize from String value – Exception while deserializing json object from restTemplate

huangapple go评论79阅读模式
英文:

no String-argument constructor/factory method to deserialize from String value - Exception while deserializing json object from restTemplate

问题

在调用以获取 JSON 响应并解析它时遇到了问题。

Person.java 模型:

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
	private String name;
	private String age;
	private Address 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 值反序列化的 String-argument 构造函数/工厂方法('{"state":"LA","country":"US"}'); 嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException: 无法构造 com.bp.model.Address 的实例(尽管至少存在一个构造函数): 没有从 String 值反序列化的 String-argument 构造函数/工厂方法('{"state":"IN","brand":"anthem"}')位于 [Source: (PushbackInputStream); line: 1, column: 325](通过引用链: java.util.ArrayList[0]->com.bp.model.Person["address"])。

注意:由于您要求只翻译代码部分,因此我只翻译了代码和异常信息。

英文:

Facing issue while making call to retrieve a json response and parse it.

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

Models:

Person.java

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

Address .java

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

Code to read this data,

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

However i get below exception,

> RestClientException while invoking ABS ServiceError while extracting response for type [java.util.List&lt;com.bp.model.Person&gt;] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of com.bp.model.Address (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"state":"LA","country":"US"}'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.bp.model.Address (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"state":"IN","brand":"anthem"}')
at [Source: (PushbackInputStream); line: 1, column: 325] (through reference chain: java.util.ArrayList[0]->com.bp.model.Person["address"])

答案1

得分: 15

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

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

去掉外层的引号和转义字符。

英文:

The code is correct but there's a problem with the JSON. The address is a string and not a JSON object. For it to work, it would need to be something like:

&quot;address&quot;: {&quot;state&quot;: &quot;LA&quot;, &quot;country&quot;: &quot;US&quot;}

Without the outer quotes and the escape characters.

答案2

得分: 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 {
        // 将JSON字符串转换为Map
        Map<String, String> map = mapper.readValue(json, Map.class);

        // 它能正常工作
        // 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 {
        // 将Map转换为JSON字符串
        String json = mapper.writeValueAsString(map);
        System.out.println(json);   // 紧凑打印

        json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
        System.out.println(json);   // 格式化打印

    } 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>
英文:

JSON string to Map:
String json = "{&quot;name&quot;:&quot;mkyong&quot;, &quot;age&quot;:&quot;37&quot;}";
Output {name=mkyong, age=37}

public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
String json = &quot;{\&quot;name\&quot;:\&quot;mkyong\&quot;, \&quot;age\&quot;:\&quot;37\&quot;}&quot;;
try {
// convert JSON string to Map
Map&lt;String, String&gt; map = mapper.readValue(json, Map.class);
// it works
//Map&lt;String, String&gt; map = mapper.readValue(json, new TypeReference&lt;Map&lt;String, String&gt;&gt;() {});
System.out.println(map);
} catch (IOException e) {
e.printStackTrace();
}
}

Map to JSON string:
{"name":"mkyong","age":"37"}
{
"name" : "mkyong",
"age" : "37"
}

public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
Map&lt;String, String&gt; map = new HashMap&lt;&gt;();
map.put(&quot;name&quot;, &quot;mkyong&quot;);
map.put(&quot;age&quot;, &quot;37&quot;);
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();
}
}

In Jackson, we can use mapper.readValue(json, Map.class) to convert a JSON string to a Map. Dependency

> <dependency>
> <groupId>com.fasterxml.jackson.core</groupId>
> <artifactId>jackson-databind</artifactId>
> <version>2.9.8</version>
> </dependency>

答案3

得分: 0

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

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

Here we can try to set the values during runtime.

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

huangapple
  • 本文由 发表于 2020年5月30日 04:35:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/62094211.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定