我有一个 EJB 应用程序,它由两个 Bean(Web 层)和(业务层)组成,其中注入了 .ServiceEJBBusinessEJBBusinessEJBServiceEJBServiceEJB从浏览器接收 HTTP 请求,调用 中的方法,获取结果,然后发送 HTTP 响应。BusinessEJB此外,还有权访问存储登录用户的对象。无权访问对象。ServiceEJBHttpSessionuserIdBusinessEJBHttpSession应用程序需要记录消息(例如,使用 sl4j/logback)。它可以在 or 中记录消息,并且当它记录消息时,它必须在日志条目中包含会话。ServiceEJBBusinessEJBuserId由于 没有 ,它需要从 中获取它。问题是实现这一目标的最佳方式是什么。我不想做的是将字段作为参数添加到 中的每个方法中,因为应用程序中有许多s和s(以及由其调用的其他bean也生成日志条目),并且我不想用该字段污染应用程序。相反,我可以在EJB级别有一个字段,但是如何填充它们?有没有办法通过注释来实现这一点?欢迎任何建议。BusinessEJBuserIdServiceEJBuserIdBusinessEJBServiceEJBBusinessEJBBusinessEJBuserIduserId@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"; } }
2 回答
DIEA
TA贡献1820条经验 获得超2个赞
一些提示/评论:
如果与应用程序服务器安全性集成,那么用户名在任何组件上都可用。EJB 可以通过调用 的注入变体来获得它,这里是:
getCallerPrincipal()
EJBContext
javax.ejb.SessionContext
@Resource private SessionContext sessionCtx;
Servlet 可以从 中检索主体。JAX-RS 组件 () 可以从 中检索它。
HttpServletRequest.getUserPrincipal()
ServiceEJB
javax.ws.rs.core.SecurityContext.getUserPrincipal()
您有什么理由不与应用程序服务器安全性集成吗?
如果您有充分的理由不与应用程序服务器安全性集成,我会提出解决方案与先前答案的变体。其变体是将应用于所有资源(servlet 过滤器或 JAX-RS)的过滤器中的用户数据设置为用户数据,这样您就不必担心在多个位置进行设置。
ContainerRequestFilter
如果您只需要用户 ID 进行日志记录,我建议您看一下 slf4j 中映射诊断上下文 (MDC) 的概念。有了它,您可以在请求开始时尽早设置用户 ID,然后使其可用于所有日志记录语句。
天涯尽头无女友
TA贡献1831条经验 获得超9个赞
创建一个请求范围的 CDI Bean,即 .UserContext
将其注入到两个 EJB 中。
在设置用户的ID和读取它。ServiceEJB
BusinessEJB
添加回答
举报
0/150
提交
取消