Jersey serializes 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) serializes the second class in JSON. And the inherited properties are found in JSON twice: with the name from the XmlElement annotation and with the name "camel-case" java-bean. Here is the code that 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 following JSON:

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

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

I examined the implementation of the JAXB marshaller and found that it was marching properties from all the superclasses of this class (which means that in my example it is impossible to get rid of the odd beanField property).

But I still hope I can skip something. Is there a way to serialize only annotated properties?

+4
source share
1 answer

To get only annotated properties, use XmlAccessType.NONE:

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

Foreign class mapping using external metadata

You can use the external metadata extension in EclipseLink JAXB (MOXy), I am a technical leader. It allows you to provide metadata for third-party classes. In this example, metadata will look like this:

 <?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 called jaxb.properties to the model classes with the following entry:

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

The following article provides instructions for setting up MOXy for working with Jersery:

Contextual Resolver - Using Metadata

You will need to use ContextResolver to force JAXBContext to use an external binding file. Metadata is defined using the property when a JAXBContext instance is created:

 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; } } 
+4
source

Source: https://habr.com/ru/post/1343168/


All Articles