sessionContext.getCallerPrincipal()中的NullPointerException

Ral*_*lph 6 java ejb glassfish java-ee cdi

我有一个简单的(webprofile)EJB 3.1应用程序,并尝试确定@ApplicationScopedCDI Bean中的当前用户,所以我使用:

Principal callerPrincipal = this.sessionContext.getCallerPrincipal()
Run Code Online (Sandbox Code Playgroud)

工作正常(所以我可以确定当前用户的名称).

但是在任何(其他)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)
Run Code Online (Sandbox Code Playgroud)

有人能给我一个提示我做错了吗?


实施细节:

Server Glassfish 3.1.2

CurrentUserService:

@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);        
    }
Run Code Online (Sandbox Code Playgroud)

面向Faces Controller和CDI服务之间的EJB Facad

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

    @Inject
    private CurrentUserService currentUserService;

    public long currentUserId() {
        return  = currentUserService.getCurrentUserId();
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

与GlassFish的web.xml

<security-role-mapping>
    <role-name>myUser</role-name>
    <group-name>APP.MY.USER</group-name>
</security-role-mapping>
Run Code Online (Sandbox Code Playgroud)

sfr*_*frj 4

它不起作用的原因是因为您的 SessionContext 对象被声明为全局变量,并且由于您使用的是 @ApplicationScope,因此在构建应用程序时仅会通过 IoC 对该资源进行一次初始化。

如果您想将 bean 保留为 @ApplicationScope,我建议您在每次需要时尝试从执行操作的方法中手动访问 SessionContext,而不是手动使用 IoC JNDI API。请参阅示例,了解如何查看 hot 来执行 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);
      }
//..

}
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣了解访问 SessionContext 的更多方法,请查看此链接,我在其中找到了代码片段:

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

我希望这有帮助