Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson: How to ignore data type mismatch for a field

I'm geting a json response in Spring Rest Template and trying to cast it on a custom object.

@JsonIgnoreProperties(ignoreUnknown = true)
public class DataItems {

private String deviceId;
    private String dataSourceName;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.ms+0000")
    private Date timestamp;
    private String mName;
    private String mVersion;
    private double value;


    /**
     * constructors and getters and setters
     */

now, sometimes, this double value I'm getting as String garbage value.

So, How to ignore those records while casting. Below is my casting code.

ObjectMapper mapper = new ObjectMapper();
DataItems dataItems =  mapper.readValue(/*String*/json),DataItems.class);

Sample Json:

[{
        "value": 26.394289,
        "deviceId": "97572545-3768-6070-0B09-1A566D8F6BC1",
        "dataSourceName": "AQM",
        "timestamp": "2016-11-04T05:24:55.000+0000",
        "mName": "SENS_TEMPERATURE",
        "mVersion": "1.0"
      },
      {
        "value": 26.396435,
        "deviceId": "97572545-3768-6070-0B09-1A566D8F6BC1",
        "dataSourceName": "AQM",
        "timestamp": "2016-11-04T05:25:58.000+0000",
        "mName": "SENS_TEMPERATURE",
        "mVersion": "1.0"
      },
      {
        "value": "{\"timestamp\": 1478220851, \"metric\": \"SENS_TAMPER\", \"value\": \"1\", \"source\": \"AQM\"}",
        "deviceId": "97572545-3768-6070-0B09-1A566D8F6BC1",
        "dataSourceName": "AQM",
        "timestamp": "2016-11-04T00:54:11.000+0000",
        "mName": "SENS_UNREGISTERED",
        "mVersion": "1.0"
      }]
like image 326
anij Avatar asked Oct 25 '25 05:10

anij


2 Answers

The custom deserializer can resolve this issue. If the double value can't be deserialized, the custom deserializer will set a default value "0.0".

Change the POJO:-

@JsonDeserialize(using = DoubleDeserializer.class)
private Double value;

DoubleDeserializer - Custom Deserializer:-

public class DoubleDeserializer extends JsonDeserializer<Double> {

    @Override
    public Double deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException, JsonProcessingException {

        String doubleValue = jsonParser.readValueAs(String.class);

        try {
            return Double.valueOf(doubleValue);
        } catch (NumberFormatException ne) {
            System.out.println("Default value is set as the value in json is not compatible with double value");
            return new Double(0);           
        }

    }
}
like image 169
notionquest Avatar answered Oct 26 '25 19:10

notionquest


You can use the type JsonNode instead of double:

@JsonIgnoreProperties(ignoreUnknown = true)
public class DataItems {
    private String   deviceId;
    private String   dataSourceName;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.ms+0000")
    private Date     timestamp;
    private String   mName;
    private String   mVersion;

    private JsonNode value;

    [...] // getters, setters
}

Now you can try to get a double from JsonNode-Object:

double value = data.getValue().asDouble(0.0); // 0.0 is default

Using this way you will not loose the other non double data:

{
    "value": "{\"timestamp\": 1478220851, \"metric\": \"SENS_TAMPER\", \"value\": \"1\", \"source\": \"AQM\"}",
    [...]
  }
like image 25
dieter Avatar answered Oct 26 '25 20:10

dieter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!