我正在学习Spring boot框架。我试图通过使用@ExceptionHandler在控制器级别实现异常处理。我能够处理抛出的用户定义异常,该异常扩展了RuntimeException,但响应比我想要看到的要多得多。它包含来自运行时异常类的原因、堆栈跟踪,但我不希望它们出现在响应中。
下面是@ExceptionHandler的代码
@ExceptionHandler(InvalidPassengerNameException.class)
public ResponseEntity<InvalidPassengerNameException> handleInvalidPassengerNameException(InvalidPassengerNameException exc) {
InvalidPassengerNameException iPNE = new InvalidPassengerNameException();
iPNE.setErrorCode("E400");
iPNE.setErrorMessage("PAssenger name should be more than 8 characters");
return new ResponseEntity<InvalidPassengerNameException>(iPNE, HttpStatus.NOT_ACCEPTABLE);
}
以下是我的用户定义异常类:
public class InvalidPassengerNameException extends RuntimeException{
private String errorCode;
private String errorMessage;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
当异常由已定义的处理程序处理时,日志中包含的内容比我想看到的要多得多:
{
"cause": null,
"stackTrace": [
{
"methodName": "handleInvalidPassengerNameException",
"fileName": "PassengerController.java",
"lineNumber": 32,
"className": "com.booking.application.controller.PassengerController",
"nativeMethod": false
},
{
"methodName": "invoke0",
"fileName": "NativeMethodAccessorImpl.java",
"lineNumber": -2,
"className": "sun.reflect.NativeMethodAccessorImpl",
"nativeMethod": true
},
{
"methodName": "invoke",
"fileName": "NativeMethodAccessorImpl.java",
"lineNumber": 62,
"className": "sun.reflect.NativeMethodAccessorImpl",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "DelegatingMethodAccessorImpl.java",
"lineNumber": 43,
"className": "sun.reflect.DelegatingMethodAccessorImpl",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "Method.java",
"lineNumber": 498,
"className": "java.lang.reflect.Method",
"nativeMethod": false
},
{
"methodName": "doInvoke",
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 190,
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"nativeMethod": false
},
{
"methodName": "invokeForRequest",
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 138,
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"nativeMethod": false
},
{
"methodName": "invokeAndHandle",
"fileName": "ServletInvocableHandlerMethod.java",
"lineNumber": 106,
"className": "org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod",
"nativeMethod": false
},
{
"methodName": "doResolveHandlerMethodException",
"fileName": "ExceptionHandlerExceptionResolver.java",
"lineNumber": 407,
"className": "org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver",
"nativeMethod": false
},
{
"methodName": "doResolveException",
"fileName": "AbstractHandlerMethodExceptionResolver.java",
"lineNumber": 61,
"className": "org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver",
"nativeMethod": false
},
{
"methodName": "resolveException",
"fileName": "AbstractHandlerExceptionResolver.java",
"lineNumber": 141,
"className": "org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver",
"nativeMethod": false
},
{
"methodName": "resolveException",
"fileName": "HandlerExceptionResolverComposite.java",
"lineNumber": 80,
"className": "org.springframework.web.servlet.handler.HandlerExceptionResolverComposite",
"nativeMethod": false
},
{
"methodName": "processHandlerException",
"fileName": "DispatcherServlet.java",
"lineNumber": 1300,
"className": "org.springframework.web.servlet.DispatcherServlet",
"nativeMethod": false
},
{
"methodName": "processDispatchResult",
"fileName": "DispatcherServlet.java",
"lineNumber": 1111,
"className": "org.springframework.web.servlet.DispatcherServlet",
"nativeMethod": false
},
{
"methodName": "doDispatch",
"fileName": "DispatcherServlet.java",
"lineNumber": 1057,
"className": "org.springframework.web.servlet.DispatcherServlet",
"nativeMethod": false
},
{
"methodName": "doService",
"fileName": "DispatcherServlet.java",
"lineNumber": 943,
"className": "org.springframework.web.servlet.DispatcherServlet",
"nativeMethod": false
},
{
"methodName": "processRequest",
"fileName": "FrameworkServlet.java",
"lineNumber": 1006,
"className": "org.springframework.web.servlet.FrameworkServlet",
"nativeMethod": false
},
{
"methodName": "doPost",
"fileName": "FrameworkServlet.java",
"lineNumber": 909,
"className": "org.springframework.web.servlet.FrameworkServlet",
"nativeMethod": false
},
{
"methodName": "service",
"fileName": "HttpServlet.java",
"lineNumber": 660,
"className": "javax.servlet.http.HttpServlet",
"nativeMethod": false
},
{
"methodName": "service",
"fileName": "FrameworkServlet.java",
"lineNumber": 883,
"className": "org.springframework.web.servlet.FrameworkServlet",
"nativeMethod": false
},
{
"methodName": "service",
"fileName": "HttpServlet.java",
"lineNumber": 741,
"className": "javax.servlet.http.HttpServlet",
"nativeMethod": false
},
{
"methodName": "internalDoFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 231,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 166,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "WsFilter.java",
"lineNumber": 53,
"className": "org.apache.tomcat.websocket.server.WsFilter",
"nativeMethod": false
},
{
"methodName": "internalDoFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 193,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 166,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilterInternal",
"fileName": "RequestContextFilter.java",
"lineNumber": 100,
"className": "org.springframework.web.filter.RequestContextFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 119,
"className": "org.springframework.web.filter.OncePerRequestFilter",
"nativeMethod": false
},
{
"methodName": "internalDoFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 193,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 166,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilterInternal",
"fileName": "FormContentFilter.java",
"lineNumber": 93,
"className": "org.springframework.web.filter.FormContentFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 119,
"className": "org.springframework.web.filter.OncePerRequestFilter",
"nativeMethod": false
},
{
"methodName": "internalDoFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 193,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 166,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilterInternal",
"fileName": "CharacterEncodingFilter.java",
"lineNumber": 201,
"className": "org.springframework.web.filter.CharacterEncodingFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 119,
"className": "org.springframework.web.filter.OncePerRequestFilter",
"nativeMethod": false
},
{
"methodName": "internalDoFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 193,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 166,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "StandardWrapperValve.java",
"lineNumber": 202,
"className": "org.apache.catalina.core.StandardWrapperValve",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "StandardContextValve.java",
"lineNumber": 96,
"className": "org.apache.catalina.core.StandardContextValve",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "AuthenticatorBase.java",
"lineNumber": 526,
"className": "org.apache.catalina.authenticator.AuthenticatorBase",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "StandardHostValve.java",
"lineNumber": 139,
"className": "org.apache.catalina.core.StandardHostValve",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "ErrorReportValve.java",
"lineNumber": 92,
"className": "org.apache.catalina.valves.ErrorReportValve",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "StandardEngineValve.java",
"lineNumber": 74,
"className": "org.apache.catalina.core.StandardEngineValve",
"nativeMethod": false
},
{
"methodName": "service",
"fileName": "CoyoteAdapter.java",
"lineNumber": 343,
"className": "org.apache.catalina.connector.CoyoteAdapter",
"nativeMethod": false
},
{
"methodName": "service",
"fileName": "Http11Processor.java",
"lineNumber": 367,
"className": "org.apache.coyote.http11.Http11Processor",
"nativeMethod": false
},
{
"methodName": "process",
"fileName": "AbstractProcessorLight.java",
"lineNumber": 65,
"className": "org.apache.coyote.AbstractProcessorLight",
"nativeMethod": false
},
{
"methodName": "process",
"fileName": "AbstractProtocol.java",
"lineNumber": 860,
"className": "org.apache.coyote.AbstractProtocol$ConnectionHandler",
"nativeMethod": false
},
{
"methodName": "doRun",
"fileName": "NioEndpoint.java",
"lineNumber": 1591,
"className": "org.apache.tomcat.util.net.NioEndpoint$SocketProcessor",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "SocketProcessorBase.java",
"lineNumber": 49,
"className": "org.apache.tomcat.util.net.SocketProcessorBase",
"nativeMethod": false
},
{
"methodName": "runWorker",
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 1149,
"className": "java.util.concurrent.ThreadPoolExecutor",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 624,
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "TaskThread.java",
"lineNumber": 61,
"className": "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "Thread.java",
"lineNumber": 748,
"className": "java.lang.Thread",
"nativeMethod": false
}
],
"errorCode": "E400",
"errorMessage": "Passenger name should be more than 8 characters",
"localizedMessage": null,
"message": null,
"suppressed": []
}
我想看到的是:
"errorCode": "E400",
"errorMessage": "Passenger name should be more than 8 characters",
我错过了什么?我知道一个全局@控制者建议会有所帮助。但是我想知道为什么会发生这种情况,以及如何实现这种情况以实现预期的输出响应?
@ExceptionHandler
工作正常。但是,您正在扩展运行时异常
,它附带了一个getCause()
,getStackTrace()
。Jackson将所有这些字段序列化为JSON,这就是为什么会看到一个stacktrace
和一个cause
字段。
为了解决这个问题,您可以为您的错误创建一个专用的DTO,该DTO不从RuntimeExctive
扩展,例如:
public class ErrorMessageDTO {
private final String errorCode;
private final String errorMessage;
// Constructors + Getters + Setters
}
现在你可以在你的@ExceptionHandler
中使用这个:
@ExceptionHandler(InvalidPassengerNameException.class)
public ResponseEntity<ErrorMessageDTO> handleInvalidPassengerNameException(InvalidPassengerNameException exc) {
ErrorMessageDTO message = new ErrorMessageDTO("E400", "Passenger name should be more than 8 characters");
return new ResponseEntity<ErrorMessageDTO>(message, HttpStatus.NOT_ACCEPTABLE);
}
或者,您可以覆盖RuntimeException
的getter,并用@JsonIgnore
注释它们:
public class InvalidPassengerNameException extends RuntimeException {
// Fields + Getters + Setters
@JsonIgnore
@Override
public Throwable getCause() {
return super.getCause();
}
}
在这种情况下,第一种解决方案是最好的。您已经在@ExceptionHandler
中返回了一个新对象,这个新对象不再需要从RuntimeException
扩展。
我有例外: 其他自定义异常从它继承: 处理它们。现在看起来就像是在那里: ExceptionHandler正确处理所有自定义异常,排除 在验证jwm-token时,此异常只在一种情况下抛出。 这样,Console中有3个stacktraces日志: 仅前端重装 请告诉我,怎么了。 附注。完整StackTrace: null 2019-07-14 17:04:38.791错误24060---[nio
我使用Spring的@ControllerAdvice和@ExceptionHandler进行异常处理。任何方法都会从Controller中抛出自定义异常,并由相应的@ExceptionHandler处理它。如果发生运行时异常(例如任何HibernateException),那么它将抛出运行时异常,并且我没有任何@ExceptionHandler用于运行时异常。
我想定义一个返回int的异常。下面给出了我的代码。它显示出错误。 solution.cc:12:22:错误:为“virtual const int BadLengthException::what()const throw()”{^~~~指定的返回类型冲突,该文件包含的文件来自/usr/include/C++/7/Exception:38:0、来自/usr/include/C++/7/IOS:39
问题内容: 我正在使用FQL从Facebook检索用户列表。为了一致性,我将结果作为JSON。这就引起了一个问题- 由于返回的JSON将用户ID编码为数字,因此json_decode()会将这些数字转换为浮点值,因为其中有些太大而不能容纳在int中;当然,我需要这些ID作为字符串。 由于json_decode()在不接受任何行为标志的情况下做自己的事情,所以我很茫然。有关如何解决此问题的任何建议?
本文向大家介绍Java异常处理运行时异常(RuntimeException)详解及实例,包括了Java异常处理运行时异常(RuntimeException)详解及实例的使用技巧和注意事项,需要的朋友参考一下 Java异常处理运行时异常(RuntimeException)详解及实例 RuntimeException RunntimeException的子类: ClassCastException
1.【强制】不要捕获Java类库中定义的继承自RuntimeException的运行时异常类,如:IndexOutOfBoundsException / NullPointerException,这类异常由程序员预检查来规避,保证程序健壮性。 正例:if(obj != null) {...} 反例:try { obj.method() } catch(NullPointerException e)