简体   繁体   English

将嵌套的 JSON 字符串反序列化为 Java Object

[英]Deserialize nested JSON String to Java Object

I have JSON looking like this, let say Question我有 JSON 看起来像这样,比如说问题

{
    "type": "String",
    "value": "{\"text\":\"Question\",\"type\":\"predefined\",\"parameter\":\"param1\",\"answers\":[\"Answer1\",\"Answer2\",\"Answer3\",\"Answear4\"]}",
    "valueInfo": {}
}

and i want to parse it with Jackson to Question objecti with object Value inside contains details about question (like text, type, and a list of answers)我想用 Jackson 将其解析为带有 object 的 Question objecti 值包含有关问题的详细信息(如文本、类型和答案列表)

i try to create classes Question and Value我尝试创建类问题和价值

public class AbasQuestion {
        @JsonProperty("type")
        String type;
        @JsonProperty("value")
        Value value;
        JsonNode valueInfo; 
} 
public class Value {

    String text;
    String type;
    String parameter;
    List<String> answers;
}

and parse string to them with并将字符串解析给他们

Question question = objectMapper.readValue(jsonQuestion, Question.class);

but stil i get error但我仍然收到错误

Can not instantiate value of type [simple type, class Value] from String value; no single-String constructor/factory method (through reference chain: Question["value"])

I understan that Value is String and i have to convert it to Value object but how and wher?我知道值是字符串,我必须将它转换为值 object 但是如何以及在哪里? inside Value constructor or inside Question setter?在 Value 构造函数内部还是在 Question setter 内部? to Jackson could do map it.到 Jackson 可以做 map 它。

You need a custom string-to-value converter.您需要一个自定义的字符串到值的转换器。 Here's an example using Spring boot as the framework.这是一个使用 Spring 引导作为框架的示例。

@JsonDeserialize(converter = StringToValueConverter.class)
Value value;

If you have a container of Value eg List<Value> then it should be contentConverter instead of converter .如果您有一个Value容器,例如List<Value>那么它应该是contentConverter而不是converter

Then your converter looks like this.然后你的转换器看起来像这样。

@Component
public class StringToValueConverter extends StdConverter<String, Value> {

  final ObjectMapper objectMapper;

  public StringToValueConverter(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
  }

  @Override
  public Value convert(String value) {
    try {
      return this.objectMapper.readValue(value, Value.class);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}

You can replace the simple RuntimeException wrapper with something more informative if you need to.如果需要,您可以将简单的RuntimeException包装器替换为提供更多信息的东西。

The members of your Value class either need to be public or better provide getter/setters that Jackson can use otherwise all the members will appear to be null after deserialization.您的Value class 的成员需要公开或更好地提供 Jackson 可以使用的 getter/setter,否则所有成员在反序列化后将显示为null

I have not worked enough with Jackson because I did not find it intuitive enough for me, but the JSON Path library did wonders for me.我对 Jackson 的工作还不够,因为我觉得它对我来说不够直观,但是 JSON 路径库为我创造了奇迹。 Moreover you can try whatever querry you want to make in online tools before you insert them into your code.此外,您可以在将在线工具插入代码之前尝试使用在线工具进行的任何查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM