当前位置: 首页 > 知识库问答 >
问题:

运动衫如何记录所有异常,但仍调用ExceptionMappers

匡凌
2023-03-14

我有点束缚...想要我的蛋糕,也吃了它。

我想记录我的应用程序抛出的所有异常。因此,如果有人点击了错误的URL,我想将堆栈跟踪记录到SLF4J。

所以你可能会想,‘嘿,这很简单,只需实现一个exceptionmapper并记录异常即可。“所以我做了:

public class RestExceptionMapper implements ExceptionMapper<java.lang.Exception> {
    private static final Logger log = LoggerFactory.getLogger(RestExceptionMapper.class);

    /**
     * {@inheritDoc}
     */
    @Override
    public Response toResponse(Exception exception) {
        log.error("toResponse() caught exception", exception);
        return null;
    }
}

如果您这样做,当有人键入错误的URL时,他们得到的不是404个错误,而是500个错误。有人猜测返回null会将异常传播到链处理程序中,但Jersey没有这样做。它实际上提供了很少的信息,为什么它会选择一个处理器而不是另一个。。。

有没有人碰到这个问题,你是怎么解决的?

共有2个答案

傅恺
2023-03-14

要返回正确的http状态代码,异常映射程序可以如下所示:

@Provider
public class RestExceptionMapper implements ExceptionMapper<Throwable>
{
    private static final Logger log = LoggerFactory.getLogger(RestExceptionMapper.class);

    @Override
    public Response toResponse(Throwable exception)
    {
        log.error("toResponse() caught exception", exception);

        return Response.status(getStatusCode(exception))
                .entity(getEntity(exception))
                .build();
    }

    /*
     * Get appropriate HTTP status code for an exception.
     */
    private int getStatusCode(Throwable exception)
    {
        if (exception instanceof WebApplicationException)
        {
            return ((WebApplicationException)exception).getResponse().getStatus();
        }

        return Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
    }

    /*
     * Get response body for an exception.
     */
    private Object getEntity(Throwable exception)
    {
        // return stack trace for debugging (probably don't want this in prod...)
        StringWriter errorMsg = new StringWriter();
        exception.printStackTrace(new PrintWriter(errorMsg));
        return errorMsg.toString();            
    }
}

此外,听起来您对级联异常映射器感兴趣,但根据规范,这是不可能的:

JAX-RS 2.0规范,第4.4章

"异常映射提供程序将检查或运行时异常映射到响应的实例。异常映射提供程序实现了ExceptionMapper接口,并且可以使用@Provider进行注释,以便自动发现。当选择异常映射提供程序来映射异常时,实现必须使用其泛型类型是异常的最近超类的提供程序

当资源类或提供程序方法引发存在异常映射提供程序的异常时,匹配的提供程序用于获取响应实例。处理结果响应的方式与web资源方法返回响应的方式相同,请参见第3.3.3节。特别是,必须使用第6章中定义的ContainerResponse筛选器链处理映射响应。

为了避免潜在的无限循环,在处理请求及其相应响应期间必须使用单个异常映射器。JAX-RS实现在处理先前从异常映射的响应时,不得尝试映射抛出的异常。相反,必须按照第3.3.4节步骤3和4中的说明处理此异常。"

田永春
2023-03-14

您可以使用RequestEventListener侦听异常事件并记录可丢弃事件,而不会干扰任何现有处理。请注意,这意味着首先注册ApplicationEventListener,然后返回RequestEventListener的实例。在一个类中实现了以下两个方面:

@Provider
public class ExceptionLogger implements ApplicationEventListener, RequestEventListener {
    
    private static final Logger log = LoggerFactory.getLogger(RequestExceptionLogger.class);
    
    @Override
    public void onEvent(final ApplicationEvent applicationEvent) {
    }

    @Override
    public RequestEventListener onRequest(final RequestEvent requestEvent) {
        return this;
    }

    @Override
    public void onEvent(RequestEvent paramRequestEvent) {
        if(paramRequestEvent.getType() == Type.ON_EXCEPTION) {
            log.error("", paramRequestEvent.getException());
        }
    }
}
 类似资料:
  • 问题内容: 我有点束缚…要我的蛋糕,也要吃。 我想记录我的应用程序引发的 所有 异常。因此,如果有人输入错误的URL,我想将堆栈跟踪记录到SLF4J。 因此,您可能会想,“嘿,这很简单,只需实现一个异常映射器并记录异常。”所以我做了: 如果您这样做,则当有人输入错误的URL时,他们会看到500错误,而不是404错误。有人猜测返回null会在链处理程序中传播异常,但是Jersey并没有这样做。实际上

  • 我希望我的ExceptionMapper捕获所有异常并记录它们。。。我现在正在使用Jersey 2.0。 我有一个异常映射器,如下所示: 此异常映射器仅在非WebApplication应用程序异常时被调用。 如何使一个全局异常映射器捕获所有异常,以便记录它们。我还有别的办法吗? 谢谢

  • 因此,我试图以通用的方式记录spring项目的控制器返回的所有未捕获的异常。我可以使用以下异常处理程序来完成此操作: 但是,对于方法的每次调用,由于方法中抛出的异常,会创建第二个错误日志:代码来自org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolveHandlerMethodExc

  • 我还尝试通过注册这个筛选器来全局设置属性: 但这也不会记录所有错误。 如何截获像上面通过调用生成的错误,以便记录它们?看来这个答案应该是显而易见的,但我已经尝试了迄今为止我能想到的一切。 或者,您可以跳过注册,只使用属性装饰单个控制器。

  • 问题内容: 我想检查特定背景文件中的错误,但是标准错误流由前台程序控制,并且问题中文件中的错误未显示。不过,我可以使用该模块并将输出写入文件。我想知道如何使用它来记录所有异常,错误及其回溯。 问题答案: 记录程序中引发的 任何 异常可能是一个坏主意,因为Python还将异常用于正常控制流。 因此,您应该只记录 未捕获的 异常。一旦有了异常对象,就可以使用记录器的方法轻松地执行此操作。 要处理所有未

  • 问题内容: 我们将Spring与slf4j和hibernate结合使用,我试图找到一种自动记录异常和错误的方法(即,无需在每个类中启动调试器的实例),以便它可以捕获抛出的任何错误或异常,并且在日志中获取类和方法的名称, 我读了一篇关于为此使用方面和拦截器的简短说明,因此您能否为我提供一些实现此目的的详细方法, 问候, 问题答案: 异常方面可能看起来像这样: spring会议: 编辑: 如果您希望记