简体   繁体   中英

Deserialize nested JSON String to Java Object

I have JSON looking like this, let say Question

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

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? inside Value constructor or inside Question setter? to Jackson could do map it.

You need a custom string-to-value converter. Here's an example using Spring boot as the framework.

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

If you have a container of Value eg List<Value> then it should be contentConverter instead of 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.

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.

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. Moreover you can try whatever querry you want to make in online tools before you insert them into your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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