注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。
以下は、JAXB 参照実装では機能しませんが、EclipseLink JAXB (MOXy) では機能します。
ジャバモデル
以下は、インターフェイスとして表された単純なドメイン モデルです。注釈を使用し@XmlType
てファクトリ クラスを指定し、これらのインターフェイスの具体的な impl を作成します。これは、アンマーシャリングを満たすために必要です (参照: http://blog.bdoughan.com/2011/06/jaxb-and-factory-methods.html )。
お客様
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(
propOrder={"name", "address"},
factoryClass=Factory.class,
factoryMethod="createCustomer")
public interface Customer {
String getName();
void setName(String name);
Address getAddress();
void setAddress(Address address);
}
住所
import javax.xml.bind.annotation.XmlType;
@XmlType(factoryClass=Factory.class, factoryMethod="createAddress")
public interface Address {
String getStreet();
void setStreet(String street);
}
工場
以下は、インターフェイスの具体的な impl を返すファクトリ メソッドです。これらは、非整列化操作中に構築される impl です。実際のクラスが必要になるのを防ぐために、Proxy
オブジェクトを活用します。
import java.lang.reflect.*;
import java.util.*;
public class Factory {
public Customer createCustomer() {
return createInstance(Customer.class); }
public Address createAddress() {
return createInstance(Address.class);
}
private <T> T createInstance(Class<T> anInterface) {
return (T) Proxy.newProxyInstance(anInterface.getClassLoader(), new Class[] {anInterface}, new InterfaceInvocationHandler());
}
private static class InterfaceInvocationHandler implements InvocationHandler {
private Map<String, Object> values = new HashMap<String, Object>();
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if(methodName.startsWith("get")) {
return values.get(methodName.substring(3));
} else {
values.put(methodName.substring(3), args[0]);
return null;
}
}
}
}
jaxb.properties
このデモを機能させるには、MOXy を JAXB プロバイダーとして指定する必要があります。これはjaxb.properties
、次のエントリを持つファイルを介して行われます ( http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.htmlを参照) 。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
デモコード
以下のデモ コードでは、マーシャリングされるインターフェイスの任意の実装を渡します。
デモ
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
AddressImpl address = new AddressImpl();
address.setStreet("123 A Street");
CustomerImpl customer = new CustomerImpl();
customer.setName("Jane Doe");
customer.setAddress(address);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
出力
以下は、デモ コードを実行した結果の出力です。
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<name>Jane Doe</name>
<address>
<street>123 A Street</street>
</address>
</customer>