备注:我是EclipseLink JAXB (MOXy)的领导和JAXB 2 (JSR-222)专家组的成员。
甲JAXB实现不需要实例化对象时使用的ObjectFactory
类。您可以配置实例可以使用@XmlType
注释通过工厂类来完成:
@XmlType(factoryClass=ObjectFactory.class, factoryMethod="createImage")
public class Image {
private String filename;
private ImageTypeEnum type;
@XmlElement(name = "imageUri")
public String getAbsoluteUri() {
// some complex computation
return uri;
}
}
如果你做到上面,那么你的JAXB实现将仍然使用Image
类派生元数据,所以它不会解决你的问题。另一种方法是使用一个XmlAdapter
这个用例:
更妙的是,当你的域对象上的属性没有一个二传手,你可以告诉你 JAXB实现(EclipseLink MOXy,地铁,阿帕奇JaxMe等)改为使用@XmlAccessorType(XmlAccessType.FIELD)
使用字段(实例变量)访问:
@XmlAccessorType(XmlAccessType.FIELD)
public class Image {
}
更新#1
如果你不能够修改域对象,那么你可能有兴趣在莫西的外部化的元数据。该扩展提供了一种通过XML的方式,为不能修改源的类提供JAXB元数据。
更多信息
更新#2 - 基于聊天的结果
图片
下面是Image
类,我会用这个例子的实现。对于getAbsoluteUri()
复杂的计算我只需添加前缀“CDN”的文件名:
package forum7552310;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement(name = "image")
public class Image {
private String filename;
private ImageTypeEnum type;
@XmlElement(name = "imageUri")
public String getAbsoluteUri() {
return "CDN" + filename;
}
}
binding.xml
下面是莫西约束力的文件我放在一起。在这个文件中我做了几件事情:
- 设置
XmlAccessorType
到FIELD
- 马克绝对URI属性为
XmlTransient
,因为我们将要代替映射filename
领域。
- 指定XmlAdapter将与
filename
字段一起使用。这是应用在getAbsoluteUri()
方法中完成的逻辑。
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum7552310">
<java-types>
<java-type name="Image" xml-accessor-type="FIELD">
<java-attributes>
<xml-element java-attribute="filename" name="imageUri">
<xml-java-type-adapter value="forum7552310.FileNameAdapter"/>
</xml-element>
<xml-transient java-attribute="absoluteUri"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
FileNameAdapter
下面是适用相同的名字算法作为getAbsoluteUri()
方法XmlAdapter
的实现:
package forum7552310;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class FileNameAdapter extends XmlAdapter<String, String> {
@Override
public String marshal(String string) throws Exception {
return "CDN" + string;
}
@Override
public String unmarshal(String adaptedString) throws Exception {
return adaptedString.substring(3);
}
}
演示
下面是演示代码演示如何创建的JAXBContext时应用绑定文件:
package forum7552310;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum7552310/binding.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Image.class}, properties);
File xml = new File("src/forum7552310/input.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
Image image = (Image) unmarshaller.unmarshal(xml);
System.out.println(image.getAbsoluteUri());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(image, System.out);
}
}
JAXB。性能
您需要包括一个名为jaxb.properties
在同一个包中的文件,内容如下为您Image
类:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
的input.xml
这里是XML我用的输入:
<?xml version="1.0" encoding="UTF-8"?>
<image>
<imageUri>CDNURI</imageUri>
</image>
输出
这里是从运行演示代码的输出:
CDNURI
<?xml version="1.0" encoding="UTF-8"?>
<image>
<imageUri>CDNURI</imageUri>
</image>
,因为我没有过Image.java控制可能是不可能的。这可以在FEImage.java上完成吗?此外,请注意absoluteUri不是Image.java中的实例级字段。它在飞行中生成。 – Sam
@Sam - 我在答案中增加了更多细节。 –
谢谢,这看起来很有希望。我已经开始实现这个,但继续运行到javax.xml.bind.JAXBException:不支持属性“eclipselink-oxm-xml”。我在与FEImage.java相同的位置指定了jaxb.properties,它是com.example.fe.domain.image。我也试过把它放在上面一层,也放在类路径中,但没有用。任何提示? – Sam