Search code examples
javaarraysjsonjacksonjson-deserialization

Deserialising 2D Array from JSON using Java/Jackson libraries throws exception


I want to deserialise a 2D array of Strings into a String[][] field using the following JSON and pojo.

Pojo Code

public class DataProcess {

    public enum Command {INSERT, UPDATE, DELETE}
    private Command command;
    private String table;
    private String[] columns;
    private String[][] values;

    public String[] getColumns() {return columns;}
    public void setColumns(String[] columns) {this.columns = columns;}
    public String[][] getValues() {return values;}
    public void setValues(String[][] values) {this.values = values;}
    public Command getCommand() {return command;}
    public void setCommand(Command command) {this.command = command;}
    public String getTable() {return table;}
    public void setTable(String table) {this.table = table;}
}

JSON to deserialise

...

    "preTestData": [{
      "columns": ["tracking_id"],
      "values": [["AAAAAAA"]],
      "command": "DELETE",
      "table": "my_table"
    }],

...

When I run the deserialising code I get the following exception

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize         
instance of java.lang.String[][] out of START_OBJECT token
at [Source: {
   "name": "Basic create shipment request",
  "preTestData": [{
    "columns": ["tracking_id"],
    "values": [["AAAAAAA"]],
    "command": "DELETE",
    "table": "my_table"
  }],

For further investigation I wrote the reverse serialising code and printed out the resulting JSON.

This was the output:

...
    "preTestData": [{
        "columns": ["tracking_id"],
        "values": [["AAAAAAA"]],
        "command": "DELETE",
        "table": "my_table"
    }],
...

Looks identical - but anyway I pasted that JSON output over the problematic part of my JSON to be deserialised.

I got exactly the same error.

Does anyone know why this error is occurring or how to fix the problem?


Solution

  • I'm not sure why the exception is being thrown. As you stated - the reverse operation produces exactly the same JSON.

    However I do have a work-around solution which is a bit clunky but will get you moving forward.

    My work-around is to replace the String[][] type with Object.

    private Command command;
    private String table;
    private String[] columns;
    private Object values;    // was String[][]
    

    Run your deserialisation code and you will see that the Jackson library represents the 2D array with the type List<List<String>>. So all that's needed is a cast and you can then access all the elements.

    List<List<String>> values = (List<List<String>>) object.getValues();
    

    I did try using List<List<String>> to directly replace String[][] in the target object, but that threw a similar exception.