XmlAdapter
の束をMarshaller
に登録できません。 Unmarshaller
ですので、各フィールドには@XmlJavaTypeAdapter
を指定する必要はありません。そのタイプはネイティブでJAXB対応ではありませんか?JAXB:@XmlJavaTypeAdapterを使用せずにXmlAdapterを使用することはできませんか?
私は幾分redundantです。
BTW、someMarshaller.setAdapter(...)
は何もしないようです。
XmlAdapter
の束をMarshaller
に登録できません。 Unmarshaller
ですので、各フィールドには@XmlJavaTypeAdapter
を指定する必要はありません。そのタイプはネイティブでJAXB対応ではありませんか?JAXB:@XmlJavaTypeAdapterを使用せずにXmlAdapterを使用することはできませんか?
私は幾分redundantです。
BTW、someMarshaller.setAdapter(...)
は何もしないようです。
これは非常に良い質問です!
短い答えは、マーシャラー/アンマーシャラーにsetAdapter
を使用すると、あなたが@XmlJavaTypeAdapter
を使用する必要がないことを意味するものではありません、なしということです。
仮定してみましょう(まだ有効です)。
一つは、次のスキーマ持つXML形式でイベントを取得し、Webアプリケーションで考えてみましょう:今すぐ
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
protected String performedBy;
}
アプリケーション:これと同等
<xs:element name="event" >
<xs:complexType>
<xs:sequence>
<!-- Avoiding other elements for concentrating on our adapter -->
<xs:element name="performedBy" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
を、あなたのモデルは次のようになりますUser
という名前のBeanを既に持っていて、ユーザーに関する詳細な情報を保持しています( )。
public class User {
private String id;
private String firstName;
private String lastName;
..
}
このUser
は、あなたのJAXBコンテキストではわかりません。 わかりやすくするために、UserはPOJOですが、任意の有効なJavaクラスを使用できます。
何アプリケーションアーキテクトたくはEvent
のperformedBy
は完全な詳細情報を得るためにUser
として表されるべきです。 @XmlJavaTypeAdapterは、画像に入ってくるのはここ
は
たJAXBContextはxs:string
としてperformedBy
程度認識しているが、それはJavaでメモリに User
として表現する必要があります。
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
@XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
UserAdapter:
修正モデルは次のようになります。Javaの:
public class UserAdapter extends XmlAdapter<String, User> {
public String marshal(User boundType) throws Exception {
..
}
public User unmarshal(String valueType) throws Exception {
..
}
}
ザ・アダプタの定義はと言う -
ご質問にお戻りになる場合 -
私はやや冗長です。
ところで、someMarshaller.setAdapter(...)は何もしないようです。
マーシャリング/アンマーシャリングに成功するには、アダプタでUserContextというクラスが必要であると考えてください。
public class UserAdapter extends XmlAdapter<String, User> {
private UserContext userContext;
public String marshal(User boundType) throws Exception {
return boundType.getId();
}
public User unmarshal(String valueType) throws Exception {
return userContext.findUserById(valueType);
}
}
ここで、UserAdapterはどのようにUserContextのインスタンスをフェッチしますか?それはインスタンス化持っている間、1は常にそれを供給しなければならない良いデザインとして ...
public class UserAdapter extends XmlAdapter<String, User> {
private UserContext userContext;
public UserAdapter(UserContext userContext) {
this.userContext = userContext;
}
public String marshal(User boundType) throws Exception {
return boundType.getId();
}
public User unmarshal(String valueType) throws Exception {
return userContext.findUserById(valueType);
}
}
しかし、JAXBランタイムは唯一の引数なしのコンストラクタでアダプタを受け入れることができます。.. (もちろんたJAXBContextは、アプリケーション特定のモデルについて知っていません)
のでありがたいオプションがあります:D
あなたはむしろ自分自身のことで、それをinstatingよりUserAdapter
の特定のインスタンスを使用するようにunmarshaller
を伝えることができます。
public class Test {
public static void main(String... args) {
JAXBContext context = JAXBContext.getInstance(Event.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
UserContext userContext = null; // fetch it from some where
unmarshaller.setAdapter(UserAdapter.class, new UserAdapter(userContext));
Event event = (Event) unmarshaller.unmarshal(..);
}
}
setAdapter
方法はMarshaller
& Unmarshaller
ノートの両方で提供されています:マーシャラー/アンマーシャラーに
setAdapter
あなたが@XmlJavaTypeAdapter
を使用する必要がないことを意味するものではありません。
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
あなたはこのJAXBランタイムは、ユーザーがあなたのバウンドタイプ&値タイプが何か他のものであることを手掛かりを持っていない省略した場合。 (有効になっている場合や、検証失敗)私たちはアダプタは引数を持つことが要求されるシナリオ、したがって 使用setAdapter
方法をとっているが、uは間違ったXML を持つ
を終了します&であるように、それはUser
をマーシャリングしようとします。
一部adavanced使い方はあなたが引数なしのコンストラクタデフォルト持って、まだあなたはアダプタ
のインスタンスを提供しても、このアダプタはマーシャル/アンマーシャリング操作が使用しているデータを、で構成されている可能性があり、そこにもあります!
あなたは "パッケージレベル" と呼ばれていますpackage-info.java
を使用することができます。
例: マーシャリング/アンマーシャリングするクラスと同じパッケージにpackage-info.javaを入れます。
mypackage.model.Aクラスとmypackage.adapterにアダプタCalendarAdapterクラスがあるとします。
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value = CalendarAdapter.class, type = Calendar.class)
})
package mypackage.model;
import java.util.Calendar;
import mypackage.adapter.CalendarAdapter;
をクラスAでCalendar型のすべてのフィールドがCalendarAdapterで整列化または非整列化されます。 は含まmypackage.modelでpackage-info.javaファイルを宣言します。
あなたはそこに有益な情報を見つけることができます: http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html
を**だから、短い答えはNOです**あなたは@XmlJavaTypeAdapterアノテーションを使用せずにXmlAdapterのを使用することはできません。 – user1128134