我正在编写一个代码,用于在运行时使用MOXy设置XmlTransient
。以下是代码的一部分,该部分改编自http://blog.bdoughan.com/2011/06/moxy-extensible-models-refresh-example.html
public void setXmlTransient(Class<?> domainClass, String propertyName) {
XmlTransient xmlTransient = new XmlTransient();
xmlTransient.setJavaAttribute(propertyName);
JavaType javaType = getJavaType(domainClass);
javaType.getJavaAttributes().getJavaAttribute().add(objectFactory.createXmlTransient(xmlTransient));
}
由于我是以编程方式执行此操作,因此我需要能够以与MOXy完全相同的方式创建propertyName
。对于大多数getter方法名称,例如getOrder
,属性名称是通过从方法名称中删除get
并将大写O
更改为小写o
来完成的,即属性名称为order
。但是,我遇到的情况是我的getter方法是getXInA
,但xInA
似乎不是有效的属性名称。 MOXy会发出类似
Ignoring attribute [xInA] on class [Atom] as no Property was generated for it.
有谁知道MOXy使用哪些规则从getter创建属性名称?或者在不阅读MOXy源代码的情况下知道我在哪里可以找到这个?
答案 0 :(得分:1)
简短回答
因为一行中有两个大写字母,所以属性名称将为XInA
。
LONG ANSWER
域模型(Foo)
下面是一个示例Java类,其中包含您问题中的属性。
package forum14945664;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Foo {
private String x;
public String getXInA() {
return x;
}
public void setXInA(String x) {
this.x = x;
}
}
MetadataSource(ExampleMetadataSource)
MetadataSource
是一种为MOXy提供映射元数据的编程方式。
package forum14945664;
import java.util.*;
import org.eclipse.persistence.jaxb.metadata.MetadataSourceAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.*;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.*;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.*;
public class ExampleMetadataSource extends MetadataSourceAdapter {
private ObjectFactory objectFactory;
private Map<Class<?>, JavaType> javaTypes;
private XmlBindings xmlBindings;
public ExampleMetadataSource() {
objectFactory = new ObjectFactory();
javaTypes = new HashMap<Class<?>, JavaType>();
xmlBindings = new XmlBindings();
xmlBindings.setPackageName("forum14945664");
xmlBindings.setJavaTypes(new JavaTypes());
}
@Override
public XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader) {
return xmlBindings;
}
public JavaType getJavaType(Class<?> clazz) {
JavaType javaType = javaTypes.get(clazz);
if(null == javaType) {
javaType = new JavaType();
javaType.setName(clazz.getSimpleName());
javaType.setJavaAttributes(new JavaAttributes());
xmlBindings.getJavaTypes().getJavaType().add(javaType);
javaTypes.put(clazz, javaType);
}
return javaType;
}
public void setXmlTransient(Class<?> domainClass, String propertyName) {
XmlTransient xmlTransient = new XmlTransient();
xmlTransient.setJavaAttribute(propertyName);
JavaType javaType = getJavaType(domainClass);
javaType.getJavaAttributes().getJavaAttribute().add(objectFactory.createXmlTransient(xmlTransient));
}
}
将MOXy指定为JAXB提供程序(jaxb.properties)
要将MOXy指定为JAXB提供程序,您需要在与域模型相同的程序包中包含名为jaxb.properties
的文件,并带有以下条目。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
的演示强> 的
在下面的演示代码中,我们将基于域模型创建一个JAXBContext
,我们将一个实例编组为XML。然后我们将使用MetadataSource
使属性成为瞬态,刷新JAXBContext
并再次封送实例。
package forum14945664;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.JAXBHelper;
public class Demo {
public static void main(String[] args) throws Exception {
ExampleMetadataSource metadata = new ExampleMetadataSource();
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadata);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);
Foo foo = new Foo();
foo.setXInA("Hello World");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
metadata.setXmlTransient(Foo.class, "XInA");
JAXBHelper.getJAXBContext(jc).refreshMetadata();
marshaller.marshal(foo, System.out);
}
}
的输出强> 的
首先我们看到XInA
属性编组,然后在我们使它成为瞬态之后,我们看到它不在第二个编组操作的XML中。
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<XInA>Hello World</XInA>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<foo/>