我有一个EJB应用程序,它由两个bean(ServiceEJB(Web层)和BusinessEJB(业务层))组成,其中在BusinessEJB中注入了ServiceEJB。ServiceEJB接收来自浏览器的HTTP请求,在BusinessEJB中调用方法,获取结果,然后发送HTTP响应。另外,ServiceEJB可以访问HttpSession对象,该对象存储了登录用户的userId。 BusinessEJB无权访问HttpSession对象。该应用程序需要记录消息(例如,使用sl4j / logback)。它可以使用ServiceEJB或BusinessEJB方法记录消息,并且在记录消息时,必须在记录条目中包含会话的userId。由于BusinessEJB没有userId,因此需要从ServiceEJB获取它。问题是实现这一目标的最佳方法是什么。我不想做的是向userId中的每个方法添加一个BusinessEJB字段作为参数,因为应用程序中有很多ServiceEJB和BusinessEJB(以及其他也会生成日志条目),并且我不想使用BusinessEJB字段来污染应用程序。相反,我可以在EJB级别上有一个userId字段,但是如何填充它们呢?有没有办法通过注释来实现这一目标?任何建议都将受到欢迎。@Produces({MediaType.APPLICATION_JSON})@Consumes({MediaType.APPLICATION_JSON})@Statelesspublic 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 }}@Statelesspublic class BusinessEJB { private String userId; public String someMethod2() { // .... log an entry with userId return "something"; }} (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 一些提示/评论:如果您与应用程序服务器安全性集成在一起,则用户名在任何组件上都可用。 EJB可以通过在getCallerPrincipal()的注入变量(这里是EJBContext)上调用javax.ejb.SessionContext来获得它:@Resourceprivate SessionContext sessionCtx;Servlet可以从HttpServletRequest.getUserPrincipal()检索主体。 JAX-RS组件(ServiceEJB)可以从javax.ws.rs.core.SecurityContext.getUserPrincipal()检索它。有什么理由不与应用程序服务器安全性集成?如果您有充分的理由不与应用程序服务器安全性集成,我建议从the previous answer提出解决方案的一种变体。差异是从应用于所有资源的过滤器(servlet过滤器或JAX-RS ContainerRequestFilter)设置用户数据,因此您不必担心在多个位置进行设置。如果只需要用户ID进行日志记录,建议您看看slf4j中的映射诊断上下文(MDC)的概念。使用它,您可以在请求开始时及早设置用户ID,并在之后将其提供给所有日志记录语句。 (adsbygoogle = window.adsbygoogle || []).push({});
07-24 15:58