Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.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 防止Spring引导应用程序中自定义异常的堆栈跟踪日志记录_Java_Spring_Logging_Exception Handling_Spring Boot - Fatal编程技术网

Java 防止Spring引导应用程序中自定义异常的堆栈跟踪日志记录

Java 防止Spring引导应用程序中自定义异常的堆栈跟踪日志记录,java,spring,logging,exception-handling,spring-boot,Java,Spring,Logging,Exception Handling,Spring Boot,在Spring Boot(mvc)中有没有一种方法可以记录一个自定义异常,并在日志文件中不显示其堆栈跟踪的情况下抛出它?但对于任何其他异常,仍然可以看到堆栈跟踪 详细解释: 我正在使用SpringBoot创建一个简单的rest服务我喜欢自定义异常,默认情况下日志中没有堆栈跟踪,json响应使用基本异常详细信息(状态、错误、消息)创建 问题是,它也不会创建任何日志条目,因此我必须手动执行此操作: 自定义异常 @ResponseStatus(value = HttpStatus.CONFLICT)

在Spring Boot(mvc)中有没有一种方法可以记录一个自定义异常,并在日志文件中不显示其堆栈跟踪的情况下抛出它?但对于任何其他异常,仍然可以看到堆栈跟踪

详细解释:

我正在使用SpringBoot创建一个简单的rest服务我喜欢自定义异常,默认情况下日志中没有堆栈跟踪,json响应使用基本异常详细信息(状态、错误、消息)创建

问题是,它也不会创建任何日志条目,因此我必须手动执行此操作:

自定义异常

@ResponseStatus(value = HttpStatus.CONFLICT)
public class DuplicateFoundException extends RuntimeException {
    public DuplicateFoundException(String message) {
        super(message);
    }
}
在服务方法中引发异常(在@RestController中)

有更多的异常会导致在每次抛出之前放置log语句,我认为这是一种糟糕的方法。我已尝试从服务方法中删除所有日志语句,并创建了@ControlledAdvice,在这里我将记录所有自定义异常,然后重新抛出它们,这样我仍然可以像以前一样获得漂亮的json:

@ControllerAdvice
public class RestExceptionHandler {
    private static final Logger log = Logger.getLogger(RestExceptionHandler.class);

    @ExceptionHandler
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            log.warn(e.getMessage());
        } else {
            log.error("...");
        }
        throw e;
    }
}
现在的问题是,我不仅看到了日志条目,还看到了自定义异常的堆栈跟踪,无法找到防止这种情况发生的方法。 我认为问题是由于再次投掷造成的。一个可能的解决方案是为异常创建一个自定义类,我将返回该类,但我不喜欢这种想法,因为异常编组似乎工作正常


有什么提示吗?谢谢。

如果不需要堆栈跟踪,可以通过在异常类中重写
fillInStackTrace
来抑制堆栈跟踪

public class DuplicateFoundException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}
调用
e.printStackTrace()
时,将不打印堆栈跟踪


另请参见。

解决方案是将异常处理留给spring boot,以便不记录自定义异常,而默认情况下记录任何其他异常。我从rest控制器中删除了@ControllerAdvice和日志语句,并将日志语句添加到自定义异常构造函数中

public DuplicateFoundException(String message) {
    super(message);
    LOGGER.warn(message);
}
我不确定这是否是最好的方法,但现在我只在一个地方有自定义异常日志记录,不必为每个异常重复log语句,也不必在日志中看到其堆栈跟踪或任何其他错误消息。

我使用的是Spring Boot 2+ 只需将此行添加到应用程序。属性:

server.error.include stacktrace=never


小心弹簧靴开发工具

尽管
服务器的默认设置是
从不
。错误。包括stacktrace
,但如果包括Spring Boot开发工具,它将始终覆盖

如果您对更多细节感兴趣,请参阅,它已成为SpringBoot2.1.0的一部分+
调用重载的超级构造函数以避免在响应中显示堆栈跟踪

public class ProductCustomException extends Exception{
    
    private static final long serialVersionUID = -291211739734090347L;

    public ProductCustomException(String message) {
        super(message,null,false,false);
    }

}
从异常类超级加载构造函数

 protected Exception(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
}

谢谢,堆栈跟踪已消失,但我仍然看到“2015-07-07 11:47:57.188错误41456---[nio-8080-exec-1].m.a.ExceptionHandlerExceptionResolver:未能调用@ExceptionHandler方法:public org.springframework.web.servlet.ModelAndView”。有没有一种方法可以消除这个问题,这样我就不会在自定义异常的日志中看到任何错误?我接受了这个答案,因为堆栈跟踪消失了,但是现在我看到我的异常消息在日志中出现了两次(1.log语句和2.failed方法的异常消息),我认为没有简单的方法可以做到这一点。也许您应该考虑不使用异常(即自定义状态代码),因为这种情况并不例外,但可以预期。我的用例基本上与官方springdoc()中的示例相同,因此我不认为它是可预期的。否则,我们也可以讨论validationException的意义。正如我在问题中所描述的,创建自定义返回对象是可能的,但如果可能的话,我试图找到更简单、更干净的解决方案。@RolandWeisleer谢谢你的回答,它真的帮助了我。因此,它进入了
log.warn
行,但也记录了整个异常?我可能错了,但我以前见过
@ExceptionHandler
s不抛出,它们只返回一个
ResponseEntity
(状态为500等),而不是FWIW…从1.3.0开始,默认为“从不”。检查@shark1608,因为发行说明确实指出,使用SpringBoot2.1.7,它被设置为“始终”default@Robber请看下面我的答案,这也许可以解释为什么它总是被设置为Hanks,欣赏它的彻底性。总是喜欢了解情况的“为什么”部分。还有一个不知道“spring boot魔力”的例子。如果您更新
application.yml
(或
application.properties
)以指定
NEVER
spring boot开发工具将尊重它(至少在2.3版中),检查您是否也覆盖了DefaultErrorAttributes,并且没有使用硬编码的includeStackTrace参数调用getErrorAttributes-就像我刚才所做的,duh!
 protected Exception(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
}