I get a JSON string that I convert to an object. One of the property within the JSON sometimes would be null. If the property is null, I want the default value to be set to 0.
This is my class:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Car {
@JsonProperty(value = "car_name")
private String carName;
@JsonProperty(value = "car_value")
private Long carValue;
@JsonProperty(value = "Specifications")
private Map<String, String> Specifications;
}
I use object mapper to convert the JSON string to the object
public List<Car> stringToCar(String json) throws JsonProcessingException {
ObjectMapper om = new ObjectMapper();
return om.readValue(json, new TypeReference<List<Car>>() {} );
}
carValue would sometimes have null value, if that happens I want it be set as 0. Is it possible to do in a efficient way rather than looping through the object and manually setting the value to 0
CodePudding user response:
You have multiple ways to do this.
1) Setter that receives long instead
This is actually not straightforward but it works. If you define the setter as follows it will do what you need:
public void setCarValue(long carValue) {
this.carValue = carValue;
}
However, this feels like a hack to me, so I would not suggest you use it.
2) Custom deserializer
This one is more complex but also much easier to understand and explicit about your intent.
public class CustomLongDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String text = jp.getText();
if (text == null || text.isEmpty()) {
return 0;
} else {
return Long.valueOf(text);
}
}
}
Then you could apply the serializer on the attribute as follows:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Car {
@JsonProperty(value = "car_name")
private String carName;
@JsonProperty(value = "car_value")
@JsonDeserialize(using = CustomLongDeserializer.class)
private Long carValue;
@JsonProperty(value = "Specifications")
private Map<String, String> Specifications;
}
Or apply it as a global deserializer to be used to deserialize every single Long
:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Long.class, new CustomLongDeserializer());
mapper.registerModule(module);
CodePudding user response:
It's not a generic solution, but in your specific use case you could use the long
primitive instead of Long
which will coerce null
to 0
when deserialized.