2011-02-08 7 views
3

REST Webサービスでインターフェイスを使用する必要があります。ここインターフェイスSpecs.javaは次のとおりです。Jersey REST/JAXBエラー、インターフェイスのマッピング

@XmlJavaTypeAdapter(MyAdapter.class) 
public interface Specs { 

    public BaseProperties getBaseProps(); 
    public void setBaseProps(BaseProperties baseProps); 

} 

MyAdapter.java:このサービスはスローアクセス

public class MyAdapter extends XmlAdapter<Object,Object> 
{ 
    public Object unmarshal(Object v) 
    { 
     return v; 
    } 
    public Object marshal(Object v) 
    { 
     return v; 
    } 
} 

RegSpecs.java

@XmlType 
public class RegSpecs implements Specs{ 
private BaseProperties baseProps; 

    public BaseProperties getBaseProps() 
    { 
     return baseProps; 
    } 
    public void setBaseProps(BaseProperties baseProps) 
    { 
     this.baseProps = baseProps; 
    } 

} 

MapSpecs.java

@XmlType 
public class MagSpecs implements Specs { 

private BaseProperties baseProps; 
private Features features; 

    public BaseProperties getBaseProps() 
    { 
     return baseProps; 
    } 
    public void setBaseProps(BaseProperties baseProps) 
    { 
     this.baseProps = baseProps; 
    } 
    public Features getFeatures() { 
     return features; 
    } 
    public void setFeatures(Features features) { 
     this.features = features; 
    } 

} 

次のエラー:

javax.xml.bind.MarshalException - リンクされた例外を持つ: [javax.xml.bind.JAXBException:クラスentities.MagSpecsもそのスーパークラスのいずれかがこのコンテキストに知られている。]

コンテキストを変更するには?私はJersey 1.5にバンドルされたJAXBを使用しています

ありがとう!

EDIT:私のコンテキストを更新しようとする試みで、私は私のクライアントにこのコードを追加した(リソース)クラス:この場合

public class BookService implements ContextResolver<JAXBContext> 
{ 

     private JAXBContext jaxbContext; 

     public BookService() { 
      try { 
       // Bootstrap your JAXBContext will all necessary classes 
       jaxbContext = JAXBContext.newInstance(Specs.class,MagSpecs.class, RegSpecs.class); 
      } catch(Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 

     public JAXBContext getContext(Class<?> clazz) { 
      if(BookService.class == clazz) { 
       return jaxbContext; 
      } 
      return null; 
     } 

私はエラーを取得する:

entities.SpecsがありますJAXBはインタフェースを処理できません。 この問題は、次の場所に関連しています。 at entities.Specs entities.Specsには引数なしのデフォルトのコンストラクタがありません。 この問題は、次の場所に関連している:entities.Specs

+0

ああ、JAXBはそこでインターフェイスを使用することはできません。代わりに抽象スーパークラスを使用してください。それはあなたを拘束すべきではありません。 JAXBアノテーション付きクラスの複雑な処理をとにかく入れておくのは良い考えではありません(おそらくデフォルト以外のコンストラクタを除いて)。 –

答えて

3

Specsインタフェースのクライアントがツーリングの目的のためにそれを見て知っているようMagSpecsはそれのインスタンスであることを知っている必要があります。これを行うための最も簡単な方法はSpecsインターフェイス上@XmlSeeAlso注釈を入れることです:私はJAXB注釈で働いていたときに、一般的には

@XmlSeeAlso({ MagSpecs.class, RegSpecs.class }) 
@XmlJavaTypeAdapter(MyAdapter.class) // Never needed this annotation myself... 
public interface Specs { 
    public BaseProperties getBaseProps(); 
    public void setBaseProps(BaseProperties baseProps); 
} 

私は、XMLスキーマができることを確認するためのテストをたくさん書くことを確認してください問題のクラスから生成され、各(正常な)エントリポイントから、クラスとインターフェイスのWebに入ることが、例外なく合理的なスキーマを生成できることがチェックされます。例えば、(と私は、これは少し長いことをお詫び申し上げます):

private SchemaOutputResolver sink; 
StringWriter schema; 

@Before 
public void init() { 
    schema = new StringWriter(); 
    sink = new SchemaOutputResolver() { 
     @Override 
     public Result createOutput(String namespaceUri, 
       String suggestedFileName) throws IOException { 
      StreamResult sr = new StreamResult(schema); 
      sr.setSystemId("/dev/null"); 
      return sr; 
     } 
    }; 
    Assert.assertTrue(schema.toString().isEmpty()); 
} 

private void testJAXB(Class<?>... classes) throws Exception { 
    JAXBContext.newInstance(classes).generateSchema(sink); 
    Assert.assertTrue(schema.toString().length() > 0); 
} 

@Test 
public void testJAXBForSpecs() throws Exception { 
    testJAXB(Specs.class); 
} 

[EDIT]:また必要がクラスにSpecsインターフェイスを変更し、現在の実装では、それを継承しています。あなたが望むならば、完全抽象クラスにすることができます。あなたがクラスに深刻な機能を入れていない限り、それはうまくいくはずです。

+0

XmlSeeAlsoを追加しました。同じエラーが発生しました。( – SlowAndSteady

+0

@Raj:うーん、私がこれらの問題を抱えていたときに働いていたのですが、シリアル化ルートの連鎖はありません。実装クラスに 'JAXBContext'をビルドするために使われたクラス)がありますが、私はそのルートが何であるか分かりません。この時点で本当に示唆できるのは、たくさんのテストに入れられ、スキーマの生成が動作することを確認します; (私はJAX-RSインターフェースで言及されたクラスごとに1つのテストを行い、全体が1つの生成されたスキーマですべてが行えることを確認するために全体的に1つあります)。 –

1

EclipseLink JAXB(MOXy)はインターフェースをXMLにマッピングできます(注:私は技術リーダーです)。REST環境に

MOXYクリーニング統合:あなたは、コンクリートのimplを返すために、対応するオブジェクトファクトリの作成方法を有することを確認する必要があり

関連する問題