-
Notifications
You must be signed in to change notification settings - Fork 111
JacksonSampleCustomViewProcessing
markwoon edited this page Feb 27, 2013
·
2 revisions
(contributed by Andrei Voden)
(copied verbatim from the mailing list)
"Hi. Instead of using class-type filtering I would like to do instance-based one. For example I have classes:
class A { String name; B info; A child; } class B { int distance; String id; } A root = new A();
Now, I would like to serialize instance root in a following way: serialize all fields that belong to the root but for root.child serialize only name. So result would be:
"root": { "name": "somthing", "info": { "distance":100, "id":"123"}, "child": {"name": "lalala"} }
... Any ideas whats the easiest way to pass filtering object along during serialization? Filtering object will probably Map object. "
And here is eventual code written to achieve custom configurable property filtering for serialization:
public class CustomSerializationView { static class ViewBean { public String name; public String value; public String secret; public ViewBean sibling; public ViewBeanChild child; public ViewBean(String name, String value, String secret) { this.name = name; this.value = value; this.secret = secret; child = new ViewBeanChild(); } } static class ViewBeanChild { public long id = 123; public String name = "child"; public String address = "123 Street"; } static class FilteredWriter extends BeanPropertyWriter { public FilteredWriter(BeanPropertyWriter w) { super(w); } public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception { BzStdSerializerProvider myprov = (BzStdSerializerProvider)prov; HashMap filter = myprov.getCurrentFilter(); if (filter == null) { super.serializeAsField(bean, jgen, prov); } else if (filter.containsKey(this._name)) { Object subfilter = filter.get(this._name); myprov.pushFilter(HashMap.class.isAssignableFrom(subfilter.getClass()) ? (HashMap)subfilter : null); super.serializeAsField(bean, jgen, prov); myprov.popFilter(); } } } public static class CustomBeanFactory extends CustomSerializerFactory // (CSF extends BeanSerializerFactory) { @Override protected BeanSerializer processViews(SerializationConfig config, BasicBeanDescription beanDesc, BeanSerializer ser, List<BeanPropertyWriter> props) { ser = super.processViews(config, beanDesc, ser, props); BeanPropertyWriter[] writers = props.toArray(new BeanPropertyWriter[props.size()]); for (int i = 0; i < writers.length; ++i) { writers[i] = new FilteredWriter (writers[i]); } ser = ser.withFiltered(writers); return ser; } } static class BzStdSerializerProvider extends StdSerializerProvider { private HashMap _filter; private Vector<HashMap> _stack = new Vector(); public BzStdSerializerProvider() { super(); } public BzStdSerializerProvider(HashMap filter) { super(); _filter = filter; } protected BzStdSerializerProvider(SerializationConfig config, StdSerializerProvider src, SerializerFactory f) { super (config, src, f); } protected BzStdSerializerProvider(SerializationConfig config, StdSerializerProvider src, SerializerFactory f, HashMap filter) { super (config, src, f); _filter = filter; } protected StdSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) { return new BzStdSerializerProvider (config, this, jsf, _filter); } public HashMap getCurrentFilter () { if (_stack.isEmpty()) return _filter; return _stack.lastElement(); } public void pushFilter (HashMap filter) { _stack.add(filter); } public void popFilter () { if (!_stack.isEmpty()) { _stack.removeElement(_stack.lastElement()); } } } public static void main(String[] args) throws Exception { // create dummy objects ViewBean bean = new ViewBean("mr bean", "goofy", "secret!"); bean.sibling = new ViewBean("sibling", "lala", "boooo"); // create filtering Map String filter = "{\"name\":0,\"value\":0, \"sibling\":{\"name\":0}, \"child\":{\"id\":0,\"address\":0}}"; ObjectMapper filterMapper = new ObjectMapper(); HashMap filterMap = filterMapper.readValue(filter, HashMap.class); // custom mapper ObjectMapper mapper = new ObjectMapper(null, new BzStdSerializerProvider(filterMap), null); mapper.setSerializerFactory(new CustomBeanFactory()); // First, without enabling view handling: System.out.println("With default serializer:"+mapper.writeValueAsString(bean)); String json = mapper.viewWriter(String.class).writeValueAsString(bean); System.out.println("With custom serializer: "+json); }
CategoryJackson