@JsonInclude(Include.NON_NULL) is not working while custom serializers are regiestered
See original GitHub issueThere is something wrong with way @JsonInclude annotations are handled. It seems like when custom serializers are attached to modules we register then @JsonInclude(Include.NON_NULL) or setSerializationIncludsion(Include.NON_EMPTY) means nothing.
My requirement is to not serialize keys for which values are null. I also want to trim string values to null (that’s why I created custom serializer which extends StdScalarSerializer).
Example input object of type let’s say MyClass:
- name: "nameOfObj1"
- producerName: "PROD CORP. "
- notes: " "
Expected output:
{
"name" : "nameOfObj1",
"producerName" : "PROD CORP."
}
I can’t get this working with Include.NON_NULL having my module with custom serializers added. Serializer itself works just fine and looks like this:
public class MyCustomStringSerializer extends StdScalarSerializer<String> {
protected MyCustomStringSerializer () {
super(String.class);
}
@Override
public void serialize(String value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonGenerationException {
String trimmedValue = StringUtils.trim(value);
if(StringUtils.isEmpty(trimmedValue)) {
jgen.writeNull();
}
else {
jgen.writeString(trimmedValue);
}
}
}
This is my object mapper where I register custom modules/serializers:
public class MyCustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 8125249677131844836L;
public MyCustomObjectMapper() {
registerModule(new MyModule());
setSerializationInclusion(Include.NON_EMPTY);
}
class MyModule extends SimpleModule {
private static final long serialVersionUID = 3012609212894483368L;
public MyModule() {
addSerializer(String.class, new MyCustomStringSerializer());
}
}
}
Using this approach I will get not exactly what I want:
{
"name" : "nameOfObj1",
"producerName" : "PROD CORP."
"notes" : null
}
There is a workaround of course. I can use some kind of mapper which will take over the work MyCustomStringSerializer currently does. The output from this mapper would be an object having all String values trimmed to nulls. Then I don’t have to register any custom modules in ObjectMapper because all the work has been done. I can rely on @JsonInclude(Include.NON_NULL) annotation on serialized object class or I can set this setting globally with setSerializationIncludsion(Include.NON_EMPTY) in MyCustomOjbectMapper constructor. With such workaround I get what I want. How to achieve t with @JsonInclude annotation ?
I used NON_NULL and NOT_EMPTY interchangeably but I think for String values these annotations mean the same thing.
Jackson version: 2.5.1
Issue Analytics
- State:
- Created 8 years ago
- Comments:16 (8 by maintainers)
Top GitHub Comments
@andrickd ok good. Just thought I’d mention. 😃
@andrickd Ok sorry: for simple String it does not change the way value serializer works (except for
@JsonFormat
handling); this would be relevant mostly for structured type serializers (POJOs, Maps, Collections).However: the whole inclusion filtering is handled by whatever calls these serializers. So if you delegate, yes, that serializer has to handle filtering out of values: delegate/child serializer must simply write out value when requested to do so. This is partly due to the common case of property value where in field name must be output by that “parent” serializer, so it has to decided for name/value pair, before delegating.
JsonGenerator.writeStringField()
in particular simply outputs field name, name, and has no concept of anything going on at databind level. Maybe javadoc should be improved to make this clear.