Vasu
Vasu

Reputation: 49

Java - convert json to complex object using jakson

This might duplicate question, but i have search a lot for solution, but no luck. I have a Class like below:

public class RestartMapState {

    public RestartMapState(List<MapStepData> vMapStepData, List<AbstractMap.SimpleEntry<String,String>> vResolvedParameters, String vJobID){
        this.vJobID=vJobID;
        this.vResolvedParameters = vResolvedParameters;
        this.vMapStepData = vMapStepData;
    }

    public RestartMapState(){}

    private List<MapStepData> vMapStepData;
    public void setvMapStepData(List<MapStepData> mapStepData){ this.vMapStepData = mapStepData; }
    public List<MapStepData> getvMapStepData(){
        return this.vMapStepData;
    }

    private List<AbstractMap.SimpleEntry<String,String>> vResolvedParameters;
    public List<AbstractMap.SimpleEntry<String,String>> getvResolvedParameters(){  return this.vResolvedParameters; }
    public void setvResolvedParameters(List<AbstractMap.SimpleEntry<String,String>> resolvedParameters){ this.vResolvedParameters = resolvedParameters; }

    private String vJobID;
    public String getvJobID(){ return this.vJobID; }
    public void setvJobID(String jobID){ this.vJobID = jobID; }
}

When i am trying this to json using following code, i am getting json file.

RestartMapState vRestartMapState = new RestartMapState(vRemainingStepsToBeExecuted, vMapResolvedParameters, vMapExCtx.getvJobID());
try {
    vObjectMapper.writerWithDefaultPrettyPrinter().writeValue(stateFile, vRestartMapState);
} catch (JsonGenerationException e) {
    isSerialized = false;
    e.printStackTrace();
} catch (JsonMappingException e) {
    isSerialized = false;
    e.printStackTrace();
} catch (IOException e) {
    isSerialized = false;
    e.printStackTrace();
}

My JSON file looks like below:

{
  "vMapStepData" : [ {
    "dependsOn" : null,
    "orderIndex" : 0,
    "name" : "Step1",
    "mapStepId" : 167119,
    "sqlstatements" : {
      "sqlstatement" : [ {
        "value" : "-- Map Step   (Step1)\nCREATE TABLE ##!sessionid##Step1\n    AS\nSELECT currency_nbr AS currency_nbr,...",
        "orderIndex" : 1,
        "isQuery" : false,
        "flags" : [ "PartOfCore" ]
      } ]
    }
  }, {
    "dependsOn" : null,
    "orderIndex" : 1,
    "name" : "Step2",
    "mapStepId" : 237822,
    "sqlstatements" : {
      "sqlstatement" : [ {
        "value" : "\n\n-- Map Step   (Step2)\nCREATE TABLE ##!sessionid##Step2\n    AS\nSELECT country_cd AS ....",
        "orderIndex" : 1,
        "isQuery" : false,
        "flags" : [ "PartOfCore" ]
      } ]
    }
  } ],
  "vResolvedParameters" : [ {
    "key" : "##RUNDATE##",
    "value" : "2018045"
  }, {
    "key" : "##julian##",
    "value" : "2018033"
  } ],
  "vJobID" : "10012"
}

But when i try to de-serialize the same json file to the object of type RestartMapState, i am getting following error.

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class java.util.AbstractMap$SimpleEntry<java.lang.String,java.lang.String>]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: C:\Users\vkukk1\.MAP_STATE_System_Test_Group_Vasu_Test_2_10012.json; line: 30, column: 5] (through reference chain: com.aexp.idn.magellan.RestartMapState["vResolvedParameters"]) RestartMapState vRestartMapState = null;

Can some one please help me to fix this, what am i doing wrong?

Upvotes: 0

Views: 436

Answers (2)

Vasu
Vasu

Reputation: 49

Finally i resolve this problem. The issue is with getter method for vResolvedParameter. I have change the getter method as below:

private List<MapStepData> vMapStepData;
public void setvMapStepData(List<MapStepData> mapStepData){ this.vMapStepData = mapStepData; }
public List<MapStepData> getvMapStepData(){ return this.vMapStepData; }

private Map<String,String> vResolvedParameters;
public Map<String,String> getvResolvedParameters() { return this.vResolvedParameters; }

Thank you @Nokolay.

Upvotes: -1

Nikolai
Nikolai

Reputation: 785

Class AbstractMap.SimpleEntry has no default constructor (without arguments) and can not be deserialized.
You should change generic type of vResolvedParameters from AbstractMap.SimpleEntry<String,String> to other type:

private List<Pair<String, String>> vResolvedParameters;
public List<Pair<String, String>> getvResolvedParameters() {
    return this.vResolvedParameters;
}
public void setvResolvedParameters(List<Pair<String, String>> resolvedParameters) {
    this.vResolvedParameters = resolvedParameters;
}

Where Pair is:

private static class Pair<K, V> {
    private K key;
    private V value;

    public K getKey() {
        return key;
    }
    public void setKey(K key) {
        this.key = key;
    }
    public V getValue() {
        return value;
    }
    public void setValue(V value) {
        this.value = value;
    }
    ...
}

You may use a Pair implementation from a lot of others libraries.

Or if value of "key" is unique you may change vResolvedParameters type to Map<String,String>. But your JSON format will be changed from:

...
"vResolvedParameters" : [ {
  "key" : "##RUNDATE##",
  "value" : "2018045"
}, {
  "key" : "##julian##",
  "value" : "2018033"
} ],
...

to:

...
"vResolvedParameters": {
  "##RUNDATE##": "2018045",
  "##julian##": "2018033"
},
...

Related qestion

Upvotes: 2

Related Questions