java - Jackson optional field empty() vs null -
i'm trying use optional in pojo indicate when json field can null, absent, or present. issue cannot figure out how configure jackson not treat optional.empty()
, null
same. empty()
, want field ignored. none of jsoninclude values seem this. jdk8module#configureabsentsasnulls()
looked promising, doesn't change results of tests. there way this?
tl;dr null
values should serialized, optional.empty()
should not serialized.
here tests exhibiting behavior i'm trying achieve.
class pojo { public optional<string> content; } private objectmapper getmapper() { return new objectmapper().registermodule(new jdk8module()); } @org.junit.test public void testabsent() throws jsonprocessingexception { objectmapper mapper = getmapper(); pojo pojo = new pojo(); pojo.content = optional.empty(); string result = mapper.writevalueasstring(pojo); assertequals("{}", result); } @org.junit.test public void testnull() throws jsonprocessingexception { objectmapper mapper = getmapper(); pojo pojo = new pojo(); pojo.content = null; string result = mapper.writevalueasstring(pojo); assertequals("{\"content\":null}", result); } @org.junit.test public void testpresent() throws jsonprocessingexception { objectmapper mapper = getmapper(); pojo pojo = new pojo(); pojo.content = optional.of("hello"); string result = mapper.writevalueasstring(pojo); assertequals("{\"content\":\"hello\"}", result); }
if check jackson documentation @jsoninclude
annotation here, used specify fields should ignored or serialized based on fields values, can see there couple of parameters (non_absent
, non_empty
) can used ignore optional.empty
values combined null
values not work in case.
what can create jsonfilter
check value of fields , ignore them if optional.empty
.
propertyfilter optionalfilter = new simplebeanpropertyfilter() { @override public void serializeasfield(object pojo, jsongenerator jgen, serializerprovider provider, propertywriter writer) throws exception { // field using writer's name (field name) field field = pojo.getclass().getdeclaredfield(writer.getfullname().tostring()); // value of field, making accessible , reverting boolean defaultaccess = field.isaccessible(); field.setaccessible(true); object value = field.get(pojo); field.setaccessible(defaultaccess); // serialize if null or not optional.empty if (value == null || value.equals(optional.empty()) == false) { writer.serializeasfield(pojo, jgen, provider); } } };
this check each field of class , serialize it, if null
or other optional.empty
.
use in main class:
filterprovider filters = new simplefilterprovider().addfilter("optionalfilter", optionalfilter); // note need `jdk8module` module value of optional objectmapper mapper = new objectmapper().registermodule(new jdk8module()); pojo pojo = new pojo(); pojo.setcontent(optional.empty()); system.out.println(mapper.writer(filters).writevalueasstring(pojo)); pojo = new pojo(); pojo.setcontent(null); system.out.println(mapper.writer(filters).writevalueasstring(pojo)); pojo = new pojo(); pojo.setcontent(optional.of("hello")); system.out.println(mapper.writer(filters).writevalueasstring(pojo));
also have annotate class filter:
@jsonfilter("optionalfilter") class pojo { }
output:
{} {"content":null} {"content":"hello"}
Comments
Post a Comment