Web Service : fine control of object marshalling

Web Service : fine control of object marshalling

When returning persisted objects in a web service, the marshaller will browse all the object tree. 2 problems can occur :

  • The object tree is huge and the resulting XML is too large.
  • Some objects have not been fetched from the database and it throws an exception.

In order to avoid that, it is possible to have a control on object marshalling by providing a custom :

  • AccessorFactory returning a custom Accessor.
  • AnnotationReader returning JAXB annotations depending on the context.

Custom AccessorFactory returning a custom Accessor

When instanciating the JAXBContext, enable the @XmlAccessorFactory annotation :

HashMap<String, Object> props = new HashMap<String, Object>();
props.put(JAXBRIContext.XMLACCESSORFACTORY_SUPPORT, true);
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] { clazz }, props);

Then you can add annotation :

@XmlAccessorFactory(value = CustomAccessorFactory.class)

Implement you CustomAccessorFactory which will return a CustomReflectionAccessor :

public class CustomAccessorFactory implements AccessorFactory {
    @Override
    public Accessor createFieldAccessor(final Class bean, final Field field, final boolean readOnly) throws JAXBException {
        return new CustomReflectionAccessor(field);
    }
    @Override
    public Accessor createPropertyAccessor(final Class bean, final Method getter, final Method setter) throws JAXBException {
        return new CustomReflectionAccessor(getter, setter);
    }
}

In the CustomReflectionAccessor you will implement get() method that way :

    @Override
    public ValueT get(final BeanT bean) throws AccessorException {
        final ValueT valueT = doGet(bean);
        if (!Hibernate.isInitialized(valueT)) {
            return null;
        }
        return valueT;
    }

There are some traps which can be avoided using the whole code :CustomReflectionAccessor

Custom AnnotationReader

It is also possible (and the two techniques can be combined) to provide a custom AnnotationReader which will return the JAXB annotations depending on the context.

HashMap<String, Object> props = new HashMap<String, Object>();
props.put(JAXBRIContext.ANNOTATION_READER, new CustomAnnotationReader());
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] { clazz }, props);

Your CustomAnnotationReader should implement AbstractInlineAnnotationReaderImpl.

No comments.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>