![](/img/trans.png)
[英]Spring Boot @ControllerAdvice Exception Handler not returning HTTP Status Text
[英]How to Prevent Stack Trace from Spring Rest API Exception Handler returning HTTP status 400
我正在尝试处理 Spring Rest 服务中的验证异常,如下所示:
@Produces("application/json")
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody ResponseEntity<ValidationErrorDTO> processValidationError(MethodArgumentNotValidException ex) {
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
ResponseEntity<ValidationErrorDTO> re = new ResponseEntity<>(processFieldErrors(fieldErrors), HttpStatus.BAD_REQUEST);
return re;
}
但是,当此代码执行时,它会返回附加到 JSON 响应的堆栈跟踪。 我想摆脱这个堆栈跟踪,只返回 JSON 错误响应。 这在 Spring 3.1 中可行吗?
{"fieldErrors":
[{"field":"type","message":"Pattern.shippingAddress.type"}]}<pre>javax.servlet.ServletException: 400 Bad Request null
at com.ebay.raptor.kernel.dispatcher.HttpDispatchCommand.execute(HttpDispatchCommand.java:142)
at com.ebay.ebox.pres.cmd.preshandler.CommandDispatchHandler.handleRequest(CommandDispatchHandler.java:59)
at com.ebay.ebox.pres.cmd.preshandler.CommandDispatchHandler.handleRequest(CommandDispatchHandler.java:13)
at com.ebay.ebox.pres.cmd.preshandler.CommandHandlerFactory$CalHandler.handleRequest(CommandHandlerFactory.java:114)
at com.ebay.ebox.pres.cmd.preshandler.CommandHandlerFactory$CalHandler.handleRequest(CommandHandlerFactory.java:75)
at com.ebay.kernel.pipeline.RequestPipeline.invoke(RequestPipeline.java:18)
at com.ebay.kernel.pipeline.RequestPipeline.invoke(RequestPipeline.java:12)
at com.ebay.kernel.pipeline.BasePipeline.callHandler(BasePipeline.java:75)
at com.ebay.kernel.pipeline.BasePipeline.execute(BasePipeline.java:53)
at com.ebay.ebox.pres.stage.BaseCommandRequestStageImpl.doWork(BaseCommandRequestStageImpl.java:64)
at com.ebay.kernel.stage.StageDriver.execute(StageDriver.java:55)
at com.ebay.ebox.pres.cmd.WebCommandImpl.execute(WebCommandImpl.java:30)
at com.ebay.raptor.web.RaptorFrontController.process(RaptorFrontController.java:338)
at com.ebay.raptor.web.RaptorFrontController.doPost(RaptorFrontController.java:554)
at com.ebay.raptor.web.RaptorGenericController.service(RaptorGenericController.java:64)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at com.ebay.raptor.kernel.filter.RaptorDispatchFilter.doFilter(RaptorDispatchFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:195)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:266)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
</pre>
您只需添加应用程序属性server.error.include-stacktrace=never
响应将堆栈跟踪包含到 400 个响应中。
你可以这样做:
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ModelAndView methodArgumentError(HttpServletRequest req, Exception exception) {
return new JsonError(exception.getMessage()).asModelAndView();
}
如果错误仅返回给用户而不用于调试,则可以在MethodArgumentNotValidException中将堆栈跟踪设置为 null。
或者,您可以使用@JsonIgnore注释覆盖getStackTrace()
@JsonIgnore
@Override
public StackTraceElement[] getStackTrace() {
return super.getStackTrace();
}
编辑:我尝试了所有其他解决方案,但没有一个对我有用。
@Order(Ordered.HIGHEST_PRECEDENCE)
在您的方法上使用 @Order(Ordered.HIGHEST_PRECEDENCE) 它将起作用
同时使用: @ResponseBody
和ResponseEntity
是不常见的。 我认为你应该清楚地决定你想要做什么。 - 然后你应该检查你的内部框架类com.ebay.raptor.kernel.dispatcher.HttpDispatchCommand
,因为这是抛出异常的那个。
另一种更简单的方法来做到这一点
public static void main(String[] args) {
System.setProperty("server.error.include-message", "never");
System.setProperty("server.error.include-stacktrace", "never");
//You can also change other important properties with this method, for example:
// System.setProperty("server.port", "8081");
// System.setProperty("server.servlet.context-path", "/api");
SpringApplication.run(YourApplication.class, args);
}
响应将如下所示;
{
"timestamp": "2021-12-30T19:23:24.002+00:00",
"status": 400,
"error": "Bad Request",
"path": "/test"
}
您可以将 Aspectj 用于这些目的。 示例http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/
您应该编写一个方面,它将捕获您的异常。
例子:
@Aspect
public class AroundExample {
@Around
pointcut = "execution(* your.package.Class.processValidationError(..))",
throwing= "error")
public Object doSomeStuff(ProceedingJoinPoint pjp, Throwable error) throws Throwable {
Object[] args = joinPoint.getArgs(); // change the args if you want to
Object retVal = pjp.proceed(args); // run the actual method (or don't)
return retVal; // return the return value (or something else)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.