'Why @JsonInclude(JsonInclude.Include.NON_EMPTY) is not working?
I am trying to set null values to database of empty values from JSON payload. This problem caused beacause I have unique constraints on social
entity fields.
I have request DTO that looks like:
@Value
@With
@Builder
@Jacksonized
public class AccountCreateRequest {
@NotBlank
String firstName;
String phone;
@Password
@NotBlank
String password;
@Email(message = "Email is not valid.")
@NotBlank
String email;
@NotBlank
String role;
SocialDto social;
}
Nested social DTO looks like
@Value
@Builder
@Jacksonized
public class SocialDto {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
String telegramId;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
String linkedinLink;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
String githubLink;
}
Json example:
{
...fields...,
social: {
telegramId: "",
githubLink: "",
...
}
}
This JSON object is deserialized with social empty strings and doesn't ignore that values. Moving annotation to the class level - didn't help for me.
How could I fix this problem?
Solution 1:[1]
@JsonInclude(JsonInclude.Include.NON_EMPTY)
does not work for the intended purpose of treating empty strings as null on object deserialization. This annotation is for including fields in Object to JSON serialization.
You need to add a custom Deserializer like so: How to deserialize a blank JSON string value to null for java.lang.String?
In order to combine this with @Jacksonized
, which already registers a @JsonDeserialize(using = x.class)
on the class level, you can do the following:
public class JsonStringDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.readValueAsTree();
String nodeText = node.asText();
// todo: isBlank or isEmpty depending on your needs
if (nodeText.isBlank()) {
return null;
}
return nodeText;
}
}
and parse the JSON object with the following code:
SimpleModule stringModule = new SimpleModule();
stringModule.addDeserializer(String.class, new JsonStringDeserializer());
ObjectMapper jsonObjectMapper = new ObjectMapper();
jsonObjectMapper.registerModule(stringModule);
jsonObjectMapper.readValue(input, modelClass);
Or you can add @JsonDeserialize(using = JsonStringDeserializer.class)
on every String field that needs it if you don't control the ObjectMapper
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |