猿问

将值传递给注入的 EJB

我有一个 EJB 应用程序,它由两个 Bean(Web 层)和(业务层)组成,其中注入了 .ServiceEJBBusinessEJBBusinessEJBServiceEJB


ServiceEJB从浏览器接收 HTTP 请求,调用 中的方法,获取结果,然后发送 HTTP 响应。BusinessEJB


此外,还有权访问存储登录用户的对象。无权访问对象。ServiceEJBHttpSessionuserIdBusinessEJBHttpSession


应用程序需要记录消息(例如,使用 sl4j/logback)。它可以在 or 中记录消息,并且当它记录消息时,它必须在日志条目中包含会话。ServiceEJBBusinessEJBuserId


由于 没有 ,它需要从 中获取它。问题是实现这一目标的最佳方式是什么。我不想做的是将字段作为参数添加到 中的每个方法中,因为应用程序中有许多s和s(以及由其调用的其他bean也生成日志条目),并且我不想用该字段污染应用程序。相反,我可以在EJB级别有一个字段,但是如何填充它们?有没有办法通过注释来实现这一点?欢迎任何建议。BusinessEJBuserIdServiceEJBuserIdBusinessEJBServiceEJBBusinessEJBBusinessEJBuserIduserId


@Produces({MediaType.APPLICATION_JSON})

@Consumes({MediaType.APPLICATION_JSON})

@Stateless

public class ServiceEJB {


    @Context

    HttpServletRequest httpRequest;


    @Inject

    private BusinessEJB bean;


    private String userId;


    @Path("someurl")

    public Response someMethod1() {

       final HttpSession session = httpRequest.getSession();

       // get the userId from the session


       String s = bean.someMethod2();


       // return Response

    }

}


@Stateless

public class BusinessEJB {


  private String userId;


  public String someMethod2() {

     // ....  log an entry with userId

     return "something";

  }   

}


青春有我
浏览 70回答 2
2回答

DIEA

一些提示/评论:如果与应用程序服务器安全性集成,那么用户名在任何组件上都可用。EJB 可以通过调用 的注入变体来获得它,这里是:getCallerPrincipal()EJBContextjavax.ejb.SessionContext@Resource private SessionContext sessionCtx;Servlet 可以从 中检索主体。JAX-RS 组件 () 可以从 中检索它。HttpServletRequest.getUserPrincipal()ServiceEJBjavax.ws.rs.core.SecurityContext.getUserPrincipal()您有什么理由不与应用程序服务器安全性集成吗?如果您有充分的理由不与应用程序服务器安全性集成,我会提出解决方案与先前答案的变体。其变体是将应用于所有资源(servlet 过滤器或 JAX-RS)的过滤器中的用户数据设置为用户数据,这样您就不必担心在多个位置进行设置。ContainerRequestFilter如果您只需要用户 ID 进行日志记录,我建议您看一下 slf4j 中映射诊断上下文 (MDC) 的概念。有了它,您可以在请求开始时尽早设置用户 ID,然后使其可用于所有日志记录语句。

天涯尽头无女友

创建一个请求范围的 CDI Bean,即 .UserContext将其注入到两个 EJB 中。在设置用户的ID和读取它。ServiceEJBBusinessEJB
随时随地看视频慕课网APP

相关分类

Java
我要回答