开发者

Jersey serialize inherited property twice

I have a java bean without any annotations. And I have a class inherited from this bean with JAXB annotations.

Jersey (JAX-RS) serialize the second class to JSON. And inherited properties occur in JSON twice: with name from XmlElement annotation and with 'camel-case' name of java-bean property. Her开发者_开发问答e is a code which illustrates this:

class MyBean {

   private Integer beanField;

   public Integer getBeanField() { return beanField; }

   public void setBeanField(Integer value) { this.beanField = value; }

}

@XmlRootElement
class AnnotatedBean extends MyBean {

  @Override
  @XmlElement(name="field")
  public Integer getBeanField() { return super.getBeanField(); }
}

}

After serialization I get the next JSON:

{ 
   "field" : 5,
   "beanField" : 5
}

(while I want it to contain only one field with name field).

I investigated JAXB marshaller implementation and found that it marshals properties from all superclasses of the given class (and that means that it's impossible to get rid of the odd beanField property in my example).

But I still hope that I could miss something. Is there a way to serialize only annotated properties?


To get only the annotated properties use XmlAccessType.NONE:

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
class AnnotatedBean extends MyBean {
    ...
}

Mapping the 3rd Party Class Using Externalized Metadata

You could use the external metadata extension in EclipseLink JAXB (MOXy), I'm the tech lead. It allows you to provide metadata for 3rd party classes. For this example the metadata will look like:

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="third.party.package">
    <java-types>
        <java-type name="MyBean" xml-transient="true"/>
    </java-types>
</xml-bindings>

To use MOXy you need to add a file named jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

The following article has instructions on configuring MOXy to work with Jersery:

  • http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-35.html

Context Resolver - Leveraging the Metadata

You would need to use a ContextResolver to get your JAXBContext to leverage the external bindings file. The metadata is specified through a property when the JAXBContext is instantiated:

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

@Provider
@Produces({"application/xml", "application/json"})
public class AnnotatedBeanContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext jaxbContext;

    public PurchaseOrderContextResolver() {
        try {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/blog/bindingfile/binding.xml"));
        jaxbContext = JAXBContext.newInstance(new Class[] {AnnotatedBean.class}, properties);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JAXBContext getContext(Class<?> clazz) {
        if(AnnotatedBean.class == clazz) {
            return jaxbContext;
        }
        return null;
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜