我有一个没有任何注释的java bean。我有一个继承自这个bean的类,带有JAXB注释。
Jersey(JAX-RS)将第二个类序列化为JSON。继承的属性在JSON中出现两次:名称来自XmlElement
注释,而“camel-case”名称为java-bean属性。这是一个代码,说明了这一点:
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(); }
}
}
序列化后,我得到下一个JSON:
{
"field" : 5,
"beanField" : 5
}
(虽然我希望它只包含一个名为field
的字段。)
我调查了JAXB marshaller实现,发现它从给定类的所有超类中编组属性(这意味着在我的示例中不可能摆脱奇怪的beanField
属性)。
但我仍然希望我能错过一些东西。有没有办法只序列化带注释的属性?
答案 0 :(得分:4)
要仅获取带注释的属性,请使用XmlAccessType.NONE:
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
class AnnotatedBean extends MyBean {
...
}
使用外化元数据映射第三方类
您可以在EclipseLink JAXB(MOXy)中使用external metadata extension,我是技术主管。它允许您为第三方类提供元数据。对于此示例,元数据将如下所示:
<?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>
要使用MOXy,您需要使用以下条目在模型类中添加名为jaxb.properties的文件:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
以下文章提供了有关配置MOXy以使用Jersery的说明:
上下文解析器 - 利用元数据
您需要使用ContextResolver来获取JAXBContext以利用外部绑定文件。在实例化JAXBContext时,通过属性指定元数据:
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;
}
}