Aymen Ragoubi Aymen Ragoubi - 3 months ago 40
JSON Question

Jackson : deserializing a map

I'm using Jackson to deserialize a json file from a HTTP Response:

ObjectMapper mapper = new ObjectMapper();
InputStream responseBody = response.getBody().in();
RawDataBody rawdataBody = mapper.readValue(responseBody, RawDataBody.class);


I also tries this but it doesn't work :

RawDataBody rawdataBody = mapper.readValue(responseBody.toString(), RawDataBody.class);


This is the error that I'm getting :

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.ubiant.hemis.accounts.TineaSeas.Model.RawDataBody out of START_ARRAY token at [Source: java.io.ByteArrayInputStream@19da0cd; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:575)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:569)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1120)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:148)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:123)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2080)
at com.ubiant.hemis.accounts.TineaSeas.Test.main(Test.java:46)


The JSON File :`

[
{
"tag":"Volume_D1_10m",
"value":0.0,
"quality":1,
"site":1,
"supplier":2,
"zone":0,
"timestamp":1470297561000
},
{
"tag":"Tmoy_T4_10m",
"value":19.2,
"quality":1,
"site":1,
"supplier":2,
"zone":0,
"timestamp":1470297561000
}
]


This is my model :`

public class RawDataBody implements Serializable {

@JsonProperty("rawDatas")
@JsonDeserialize
private ArrayList<RawData> rawDatas = new ArrayList<RawData>();

public RawDataBody(){
}

public RawDataBody rawDatas(ArrayList<RawData> rawDatas) {
this.rawDatas = rawDatas;
return this;
}

@JsonProperty("rawDatas")
public ArrayList<RawData> getRawDatas() {
return rawDatas;
}

@JsonProperty("rawDatas")
public void setRawDatas(ArrayList<RawData> rawDatas) {
this.rawDatas = rawDatas;
}


public class RawData implements Serializable {

private String tag = null;
private Double value = null;
private Integer quality = null;
private Integer site = null;
private Integer supplier = null;
private Integer zone = null;
private BigDecimal timestamp = null;


@JsonProperty("tag")
public String getTag() {
return tag;
}

@JsonProperty("tag")
public void setTag(String tag) {
this.tag = tag;
}

@JsonProperty("value")
public Double getValue() {
return value;
}

@JsonProperty("value")
public void setValue(Double value) {
this.value = value;
}


@JsonProperty("quality")
public Integer getQuality() {
return quality;
}

@JsonProperty("quality")
public void setQuality(Integer quality) {
this.quality = quality;
}


@JsonProperty("site")
public Integer getSite() {
return site;
}
@JsonProperty("site")
public void setSite(Integer site) {
this.site = site;
}


@JsonProperty("supplier")
public Integer getSupplier() {
return supplier;
}

@JsonProperty("supplier")
public void setSupplier(Integer supplier) {
this.supplier = supplier;
}



@JsonProperty("zone")
public Integer getZone() {
return zone;
}
@JsonProperty("zone")
public void setZone(Integer zone) {
this.zone = zone;
}
@JsonProperty("timestamp")
public BigDecimal getTimestamp() {
return timestamp;
}

@JsonProperty("timestamp")
public void setTimestamp(BigDecimal timestamp) {
this.timestamp = timestamp;
}


}

Can anyone help me with this ?

Answer

There are two possible approaches:

Approach 1

Considering the existing JSON:

[
  {
    "tag": "Volume_D1_10m",
    "value": 0,
    "quality": 1,
    "site": 1,
    "supplier": 2,
    "zone": 0,
    "timestamp": 1470297561000
  },
  {
    "tag": "Tmoy_T4_10m",
    "value": 19.2,
    "quality": 1,
    "site": 1,
    "supplier": 2,
    "zone": 0,
    "timestamp": 1470297561000
  }
]

It can be serialized into a RawData array, as following:

String json = "[{\"tag\":\"Volume_D1_10m\",\"value\":0.0,\"quality\":1,\"site\":1,\"supplier\":2,\"zone\":0,\"timestamp\":1470297561000},{\"tag\":\"Tmoy_T4_10m\",\"value\":19.2,\"quality\":1,\"site\":1,\"supplier\":2,\"zone\":0,\"timestamp\":1470297561000}]";
ObjectMapper mapper = new ObjectMapper(); 
RawData[] rawDataArray = mapper.readValue(json, RawData[].class);

Approach 2

Modify your JSON to be like:

{
  "rawDatas": [
    {
      "tag": "Volume_D1_10m",
      "value": 0,
      "quality": 1,
      "site": 1,
      "supplier": 2,
      "zone": 0,
      "timestamp": 1470297561000
    },
    {
      "tag": "Tmoy_T4_10m",
      "value": 19.2,
      "quality": 1,
      "site": 1,
      "supplier": 2,
      "zone": 0,
      "timestamp": 1470297561000
    }
  ]
}

And then serialize it into a RawDataBody:

String json = "{\"rawDatas\":[{\"tag\":\"Volume_D1_10m\",\"value\":0.0,\"quality\":1,\"site\":1,\"supplier\":2,\"zone\":0,\"timestamp\":1470297561000},{\"tag\":\"Tmoy_T4_10m\",\"value\":19.2,\"quality\":1,\"site\":1,\"supplier\":2,\"zone\":0,\"timestamp\":1470297561000}]}";
ObjectMapper mapper = new ObjectMapper();
RawDataBody rawDataBody = mapper.readValue(json, RawDataBody.class);