備註:我是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