7

私は単純な (webprofile) EJB 3.1 アプリケーションを持っており、@ApplicationScopedCDI Bean 内の現在のユーザーを特定しようとしているので、次を使用します。

Principal callerPrincipal = this.sessionContext.getCallerPrincipal()

これは正常に機能します (そのため、現在のユーザーの名前を特定できます)。

しかし、(他の) EJB で例外が発生すると、この呼び出しは機能しなくなります (サーバーを再起動する必要があります)。呼び出し元のプリンシパルを返す代わりに、メソッドはこの例外をスローします。

Caused by: java.lang.NullPointerException
at com.sun.ejb.containers.EJBContextImpl.getCallerPrincipal(EJBContextImpl.java:421)
at de.mytest.service.CurrentUserService.getCurrentUserId(CurrentUserService.java:102)

誰かが私が間違っていることのヒントを教えてくれますか?


実装の詳細:

サーバー Glassfish 3.1.2

現在のユーザー サービス:

@ApplicationScoped
public class CurrentUserService {

    @Resource
    private SessionContext sessionContext;

 public long getCurrentUserId() {

        if (this.sessionContext == null) {
            throw new RuntimeException("initialization error, sessionContext must not be null!");
        }

 /*line 102 */     Principal callerPrincipal = this.sessionContext.getCallerPrincipal(); 
        if (callerPrincipal == null) {
            throw new RuntimeException("callerPrincipal must not be null, but it is");
        }

        String name = callerPrincipal.getName();
        if (name == null) {
            throw new RuntimeException("could not determine the current user id, because no prinicial in session context");
        }

        return this.getUserIdForLogin(name);        
    }

Faces Controller と CDI Service の間で抵抗する EJB Facad

@Stateless
@RolesAllowed("myUser")
public class TeilnehmerServiceEjb {

    @Inject
    private CurrentUserService currentUserService;

    public long currentUserId() {
        return  = currentUserService.getCurrentUserId();
    }
}

web.xml

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All Pages</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>myUser</role-name>
    </auth-constraint>
</security-constraint>

<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>mySecurityRealm</realm-name>
</login-config>

glassfish-web.xml

<security-role-mapping>
    <role-name>myUser</role-name>
    <group-name>APP.MY.USER</group-name>
</security-role-mapping>
4

1 に答える 1

4

機能しない理由は、SessionContext オブジェクトがグローバル変数として宣言されており、@ApplicationScope を使用しているため、アプリのビルド時に IoC を介したそのリソースの初期化が 1 回だけ行われるためです。

Bean を @ApplicationScope として保持したい場合は、アクションを実行するメソッド内から手動で必要になるたびに SessionContext にアクセスすることをお勧めしますが、IoC の代わりに JNDI API を手動で使用します。以下を使用して手動でリソースにアクセスするために JNDI ルックアップを実行するホットを表示する方法の例を参照してください。

public long getCurrentUserId() {
      //..
     try {
          InitialContext ic = new InitialContext();
          SessionContext sessionContext=(SessionContext)   ic.lookup("java:comp/env/sessionContext");

          System.out.println("look up injected sctx: " + sessionContext);

     //Now do what you want with the Session context:
         Principal callerPrincipal = sessionContext.getCallerPrincipal();
    //..
      } catch (NamingException ex) {
          throw new IllegalStateException(ex);
      }
//..

}

SessionContext にアクセスするその他の方法について知りたい場合は、コード スニペットを見つけた次のリンクを参照してください。

http://javahowto.blogspot.com/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html

これが役立つことを願っています

于 2012-05-17T13:41:12.197 に答える