Home > Software engineering >  Cannot deserialize value of type `[Ljava.lang.String;` from Object value (token `JsonToken.START_OBJ
Cannot deserialize value of type `[Ljava.lang.String;` from Object value (token `JsonToken.START_OBJ

Time:06-11

I am trying to parse the following JSON to POJO, specifically the payload I want to extract as String[] or List of String without losing the JSON format.

{
  "payLoad": [
    {
      "id": 1,
      "userName": null,
      "arName": "A1",
      "areas": []
    },
    {
      "id": 2,
      "userName": "alpha2",
      "arName": "A2",
      "areas": []
    }
  ],
  "count": 2,
  "respCode": 200
}

Here is the POJO that I am using -

public class Response {

    @JsonProperty("count")
    private int totalCount;

    @JsonProperty("respCode")
    private int responseCode;

    @JsonProperty("payLoad")
    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private String[] transactionsList;

    public String[] getTransactionsList() {
        return transactionsList;
    }

    public void setTransactionsList(String[] transactionsList) {
        this.transactionsList = transactionsList;
    }
..
}

This is method I am using with springboot to parse it automatically to

public void transactionsReceived() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Response responseRcvd = objectMapper.readValue(jsonString, Response.class); 
}

Here is an error I am getting -

    Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `[Ljava.lang.String;` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: (String)"{"payLoad": [{"id": 1,"userName": null,"arName": "A1","areas": []},{"id": 2,"userName": "alpha2","arName": "A2","areas": []}],"count": 2,"respCode": 200}"; line: 1, column: 14] (through reference chain: com.example.demo.model.Response["payLoad"]->java.lang.Object[][0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1741)..

CodePudding user response:

You can write custom deserializer:

  public class JsonObjectListDeserializer extends StdDeserializer<List<String>> {

    public JsonObjectListDeserializer() {
      super(List.class);
    }

    @Override
    public List<String> deserialize(JsonParser parser, DeserializationContext context) throws IOException, JacksonException {
      JsonNode node = parser.getCodec().readTree(parser);
      List<String> result = new ArrayList<>();
      if (node.isArray()) {
        for (JsonNode element : node) {
          result.add(element.toString());
        }
      } else if (node.isObject()) {
        result.add(node.toString());
      } else {
        //maybe nothing?
      }
      return result;
    }
  }

JsonNode.toString() returns json representation of the node, like this you revert the node back to json to save in list.

Then register the deserializer only for this particular field.

public static class Response {

    @JsonProperty("count")
    private int totalCount;

    @JsonProperty("respCode")
    private int responseCode;

    @JsonProperty("payLoad")
    @JsonDeserialize(using = JsonObjectListDeserializer.class)
    private List<String> transactionsList;

    //getters, setters, etc.
  }
  • Related