Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有日志记录和嵌套EJB调用的EJB拦截器_Java_Logging_Ejb 3.0_Interceptor_Mdc - Fatal编程技术网

Java 具有日志记录和嵌套EJB调用的EJB拦截器

Java 具有日志记录和嵌套EJB调用的EJB拦截器,java,logging,ejb-3.0,interceptor,mdc,Java,Logging,Ejb 3.0,Interceptor,Mdc,我试图通过拦截器为EJB调用应用常规日志记录。此日志应该记录bean的安全主体。该方法使用MDC,将主体推送到MDC,并在方法调用完成时将其删除 然而,当在EJB中进行EJB方法调用时,这种方法会失败。请参阅下面的演示代码。有没有解决这个问题的办法或更好的办法 public class LoggingInterceptor { @Resource protected SessionContext sessionCtx; @AroundInvoke public

我试图通过拦截器为EJB调用应用常规日志记录。此日志应该记录bean的安全主体。该方法使用MDC,将主体推送到MDC,并在方法调用完成时将其删除

然而,当在EJB中进行EJB方法调用时,这种方法会失败。请参阅下面的演示代码。有没有解决这个问题的办法或更好的办法

public class LoggingInterceptor {

    @Resource
    protected SessionContext sessionCtx;

    @AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
        Principal principal = sessionCtx.getCallerPrincipal();
        if (principal != null) {
            MDC.put("USER_KEY", principal.getName());
        }
        try {
            return ctx.proceed();
        } finally {
            MDC.remove("USER_KEY");
        }
    }
}
现在,我尝试将其用于会话bean,如下所示:

@Stateless
@Interceptors(LoggingInterceptor.class)
public class Bean1 {

    private static Logger logger = Logger.getLogger(Bean1.class);

    @Resource
    Bean2 bean2;

    public String doSomething() {
        logger.debug("Step1.");
        bean2.doMore();
        logger.debug("Step2.");
和bean 2:

@Stateless
@Interceptors(LoggingInterceptor.class)
public class Bean2 {

    private static Logger logger = Logger.getLogger(Bean2.class);

    public String doMore() {
        logger.debug("Step in Bean2.");
直接调用Bean2时,日志工作:

23:53:00,093 DEBUG [Bean2] [testuser] Step in Bean2. 
但是,当调用Bean1时,第二个log语句不再包含该用户,因为Bean2截获的最后一个块已将UserKey从MDC中删除:

23:53:00,093 DEBUG [Bean1] [testuser] Step1.
23:53:00,193 DEBUG [Bean2] [testuser] Step in Bean2.
23:53:00,293 DEBUG [Bean1] [] Step2.

在拦截器中继续之前,可以存储以前的主体名称

@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
    Principal principal = sessionCtx.getCallerPrincipal();
    String previousPrincipalName = MDC.get("USER_KEY");

    MDC.put("USER_KEY", principal == null ? "" : principal.getName());

    try {
        return ctx.proceed();
    } finally {
        MDC.put("USER_KEY", previousPrincipalName);
    }
}

但是有了这个提议,我将永远不会删除MDC中的用户。这很重要吗?如果在调用方法之前没有用户,那么在调用之后,MDC中的user_键将等于null。当然,可以对代码进行增强,以便将其从地图中删除,但想法保持不变。