2016-03-29 6 views
0

パスからのパラメータで初期化する必要があり、注入する必要のあるEJBへの参照を含むサブリソースクラスがあります。Jax-rs initial subresource注入に使用できるオブジェクトがありません

リソースクラス:

@Path("widgets") 
public class MasterResource{ 
    @Inject 
    WidgetBean widgets; 

    @Context 
    ResourceContext rc; 

    @Path("{year}") 
    public WidgetArchives wArchives(@PathParam("year") String year){ 
     return rc.initResource(new WidgetArchiveResource(year)); 
    } 
} 

サブリソースクラス

public class WidgetArchiveResource{ 
    @Inject 
    WidgetBean widgets; 

    public WidgetArchiveResource(String year){ 
     ....code 
    } 

    @GET 
    public String doGet(){ 
     ....code using WidgetBean 
    } 
} 

私は一年で取得呼び出すと、私は次のエラーを参照してください。

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=WidgetBean,parent=WidgetArchiveResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,542790913) 

を、私は、Javaに新たなんですEE。私は間違って何をしていますか?

+0

はWidgetArchiveResource'はなく、手動でnew' 'でこのクラスを作成し'注入するようにしてください。デフォルトコンストラクタを提供し、メソッドを使用して年を設定します。 beans.xmlに 'bean-discovery-mode =" all "'を使用したいかもしれません。 – simdevmon

+0

これは私のための学習の一種です。私はinitresourceがこのように使われているのを見てきました。私はそれを理解しようとしています。 – KG6ZVP

答えて

2

メソッドrc.initResourceは、リソースにいくつかの依存関係を注入する必要がある場合(たとえば、@Injectによって注釈が付けられた場合)にのみ意味があります。これは、依存関係をBeanに注入するためのJAX-RS固有の方法です。依存関係を注入する好ましい方法がCDI経由の完全なJavaEE環境では推奨されていません。 rc.initResourceは、すべてのCDI Beanを注入しません(たとえば、@EJBは動作可能ですが、@Inject notは動作します)。

JavaEEでは、達成したいことをするための好ましい方法は、WidgetArchiveResourceを親MasterResourceに挿入することです。 CDI Beanは引数のないコンストラクタを持つ必要がありますが、setterを使用して年を渡すことができます。 、あなたがbean-discovery-mode="all"とあなたのWEB-INFフォルダにbeans.xmlのを持っていなければならないのいずれか、また

@Path("widgets") 
@RequestScoped 
public class MasterResource{ 
    @Inject 
    Instance<WidgetArchiveResource> waResources; 

    @Path("{year}") 
    public WidgetArchives wArchives(@PathParam("year") String year){ 
     WidgetArchiveResource waResource = waResources.get(); 
     waResource.setYear(year); 
     return waResource; 
    } 
} 

:あなたが要求スコープであなたのマスターresouceを置く場合は、同時要求のために安全なそれを作る、要求ごとに再作成されますまたは明示的に資格CDI作るためにあなたのWidgetArchiveResourceに依存スコープを追加します。

@Dependent 
public class WidgetArchiveResource { 
    public WidgetArchiveResource() {} // optional no arg constructor 
} 
+0

「ウィジェット」パス上の何かが呼び出されるたびに、WidgetArchiveResourceをインスタンス化することなくこれを行う方法はありますか? – KG6ZVP

+0

より大きな範囲に割り当てることができます。最大のスコープは '@ ApplicationScoped'です。つまり、一度作成された後、アプリケーションが終了するまで再利用されます。 @Dependentを削除し、 '@ ApplicationScoped'を追加することができます。 '@ RequestScoped'ではなく、' MasterResource'をこのようにマークすることもできます。しかし、RESTリクエストの間に状態を保存するべきではないことを念頭に置いておいてください。そのため、@ @ RequestScopedをお薦めします。 – OndrejM

+0

要求に使用されていなくても、すべてのサブリソースをインスタンス化せずにMasterでRequestScopedを使用する方法はありません。 – KG6ZVP

関連する問題