2

I created a new Custom Deserializer, which when an empty string is present in a json this is returned as a null

public class CustomDeserializer extends JsonDeserializer<User> {
@Override
public User deserialize(JsonParser jsonParser, DeserializationContext context) throws
    IOException {
    JsonNode node = jsonParser.readValueAsTree();
    String firstName = null;
    String lastName = null;
    String age = null;
    String address = null;
    if(node.has("firstName") && !node.get("firstName").asText().isEmpty()) {
        firstName = node.get("firstName").asText();
    }
    if(node.has("lastName") && !node.get("lastName").asText().isEmpty()) {
        lastName = node.get("lastName").asText();
    }
    if(node.has("age") && !node.get("age").asText().isEmpty()) {
        age = node.get("age").asText();
    }
    if(node.has("address") && !node.get("address").asText().isEmpty()) {
        address = node.get("address").asText();
    }
    if(firstName == null && lastName == null && age == null && address == null) {
        return null;
    }
    return new User(firstName, lastName, age, address);
}

My problem is from the performance point of view. I would like to optimize the fact of having to change the Deserializer at every possible change of field. Is it possible to optimize yours? I was thinking about using Reflaction but I don't know how to do it. It's possible ?

Jacket
  • 353
  • 6
  • 18
  • Why do you want to optimize it? Is it a performance issue? Or are you thinking about maintenance? – Ghokun Mar 17 '21 at 11:00
  • @Ghokun Maintenance, I don't like having to change the deserializer every time at every possible change of the Json fields – Jacket Mar 17 '21 at 11:07
  • 1
    @Jacket, please, see the [deserializer I provided]((https://stackoverflow.com/a/66630142/13942448)) in your [previous question](https://stackoverflow.com/questions/66597864/jsondeserializer-does-not-work-on-the-class-but-only-on-the-single-element-of-th/66630142): it it based on reflection indeed, and I included it in the answer just for this reason, in order to give you a more suitable and maintainable deserializer than the one provided in the other answers which are, more tightly coupled to a specific use case. Please, see the updated version of the code, I think it should work properly. – jccampanero Mar 17 '21 at 11:17

1 Answers1

1

I would suggest another approach. Instead of using a CustomDeserializer for User, I would rather write a custom deserializer for String. Then you can use this deserializer for the string properties of your User class, where you want to treat an empty string as null. This also makes maintenance easier whenever you need to change the properties of your User class.

public class User {

    @JsonDeserialize(using = CustomStringDeserializer.class)
    private String firstName;

    @JsonDeserialize(using = CustomStringDeserializer.class)
    private String lastName;

    @JsonDeserialize(using = CustomStringDeserializer.class)
    private String age;

    @JsonDeserialize(using = CustomStringDeserializer.class)
    private String address;
    
    // getters and setters omitted here for brevity
}

The custom string deserializer can be implemented very easy by extending Jackson's StringDeserializer.

public class CustomStringDeserializer extends StringDeserializer {

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = super.deserialize(p, ctxt);
        if (value != null && value.isEmpty())
            value = null;     // replace empty string by null
        return value;
    }
}
Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49