2011-07-28 11 views

答えて

18

これは非常に良い質問です!

短い答えは、マーシャラー/アンマーシャラーに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クラスを使用できます。

何アプリケーションアーキテクトたくはEventperformedByは完全な詳細情報を得るために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 { 
      .. 
    } 
} 

ザ・アダプタの定義はと言う -

  1. BoundTypeは(Memeory表現で)ユーザー
  2. ValueTypeにはStringですが(データ型JAXBコンテキストを意識している)である

ご質問にお戻りになる場合 -

私はやや冗長です。

ところで、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

ノートの両方で提供されています:マーシャラー/アンマーシャラーに

  1. setAdapterあなたが@XmlJavaTypeAdapterを使用する必要がないことを意味するものではありません。

    @XmlRootElement(name="event") 
    @XmlType(name="") 
    public class Event { 
    
        @XmlElement(required=true) 
        // @XmlJavaTypeAdapter(UserAdapter.class) 
        protected User performedBy; 
    } 
    

    あなたはこのJAXBランタイムは、ユーザーがあなたのバウンドタイプ&値タイプが何か他のものであることを手掛かりを持っていない省略した場合。 (有効になっている場合や、検証失敗)私たちはアダプタは引数を持つことが要求されるシナリオ、したがって 使用setAdapter方法をとっているが、uは間違ったXML を持つ

  2. を終了します&であるように、それはUserをマーシャリングしようとします。

    一部adavanced使い方はあなたが引数なしのコンストラクタデフォルト持って、まだあなたはアダプタ

    のインスタンスを提供しても、このアダプタはマーシャル/アンマーシャリング操作が使用しているデータを、で構成されている可能性があり、そこにもあります!

+11

を**だから、短い答えはNOです**あなたは@XmlJavaTypeAdapterアノテーションを使用せずにXmlAdapterのを使用することはできません。 – user1128134

5

あなたは "パッケージレベル" と呼ばれています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

関連する問題