Springboot捕获全局异常404-NoHandlerFoundException及Swagger/静态路由处理
Posted OkidoGreen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot捕获全局异常404-NoHandlerFoundException及Swagger/静态路由处理相关的知识,希望对你有一定的参考价值。
1、解决Spring MVC no handler抛出异常 - 简书 (jianshu.com)https://www.jianshu.com/p/80e7b7fc374e
现如今每一个网站都会有自己的404页面,但是作为一个纯后端的应用,肯定是没有静态资源的,这辈子也不可能会有静态资源
对于Spring MVC它有自己的一套404返回,例如这样
"timestamp": "2018-09-26T17:03:41.161+0800",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/process-instance/overview1"
但是肯定不是我们所希望的
如果使用的是Spring Boot,可以在application.properties中设置
spring.mvc.throw-exception-if-no-handler-found=true
该参数对应的就是DispatcherServlet中的throwExceptionIfNoHandlerFound
再在全局异常处理中利用@ExceptionHandler捕获NoHandlerFoundException就可以了
但是并没有生效,原因是Spring会默认给你加上ResourceHttpRequestHandler这个handler,也就不会出现noHandler的情况了,该handler是用来处理资源使用的
spring.resources.add-mappings=false
如上配置就可以了
mvc:
throw-exception-if-no-handler-found: true
resources:
add-mappings: false
spring.resources.add-mappings=false 为静态资源设置默认处理
spring.mvc.throw-exception-if-no-handler-found=true
这样可以将自定义全局404异常方便Restful使用
但是spring.resources.add-mappings=false会导致swagger也不能访问。
如需swagger能正常访问,需指定swagger的静态资源处理。
处理流程:
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfiguration implements WebMvcConfigurer
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
3、全局异常处理
@ControllerAdvice
public class BaseExceptionHandler
private final static Logger logger = LoggerFactory.getLogger(BaseExceptionHandler.class);
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> noRequestHandlerFoundExceptionHandler(MissingServletRequestParameterException e)
String errorCode = "B0400";
String errorMsg = "Bad Request";
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.BAD_REQUEST);
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e)
String errorCode = "REQCTERROR";
String errorMsg = "ContentType错误";
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.INTERNAL_SERVER_ERROR);
@ExceptionHandler(MultipartException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleMultipartException(MultipartException e)
String errorCode = "REQCTERROR";
String errorMsg = "enctype must be multipart/form-data";
logger.error(" MultipartException: " + e);
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.INTERNAL_SERVER_ERROR);
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleNoHandlerFoundException(Exception e)
String errorCode = "404";
String errorMsg = "找不到对应资源";
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.NOT_FOUND);
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleHttpRequestMethodNotSupportedException(Exception e)
String errorCode = "404";
String errorMsg = "找不到对应资源";
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.NOT_FOUND);
@ExceptionHandler(TokenTimeOutException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleTokenTimeOutException(TokenTimeOutException e)
return new ResponseEntity<>(new ErrorResponse(e.getCode(), e.getMsg()), HttpStatus.NOT_FOUND);
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleException(Exception e)
String errorCode = "SYSERROR";
String errorMsg = "系统繁忙,请稍后再试";
if (e != null && e.getMessage() != null &&
e.getMessage().contains("你的主机中的软件中止了一个已建立的连接"))
return null;
if (e != null)
logger.error(" Exception: " + e.getClass().toString() + "\\n" + getExceptionAllinformation(e));
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.INTERNAL_SERVER_ERROR);
@ExceptionHandler(ForbiddenException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleForbiddenException(ForbiddenException e)
String errorCode = e.getCode();
String errorMsg = e.getMsg();
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.FORBIDDEN);
@ExceptionHandler(DLException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleDLException(DLException e)
String errorCode = e.getCode();
String errorMsg = e.getMsg();
if(e instanceof ParamEncryptExcption)
errorCode = "SYSERROR";
errorMsg = "系统繁忙,请稍后再试";
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.INTERNAL_SERVER_ERROR);
@ExceptionHandler(UndeclaredThrowableException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleUndeclaredThrowableException(UndeclaredThrowableException e)
Throwable throwable = e.getUndeclaredThrowable();
String errorCode = "";
String errorMsg = "";
if (throwable != null && throwable instanceof DLException)
errorCode = ((DLException) throwable).getCode();
errorMsg = ((DLException) throwable).getMsg();
else
errorCode = "SYSERROR";
errorMsg = "系统繁忙,请稍后再试";
logger.error(" Exception: " + e.getClass().toString() + "\\n" + getExceptionAllinformation(e));
return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.INTERNAL_SERVER_ERROR);
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
BindingResult result = e.getBindingResult();
List<String> errors = new ArrayList<>();
if (result.hasFieldErrors())
List<FieldError> fieldErrorList = result.getFieldErrors();
for (FieldError error : fieldErrorList)
// errors.add(error.getField() + ":" +error.getDefaultMessage());
errors.add(error.getDefaultMessage());
return new ResponseEntity<>(new ErrorResponse("400", errors.toString()), HttpStatus.BAD_REQUEST);
public static String getExceptionAllinformation(Exception ex)
StringBuilder sOut = new StringBuilder();
StackTraceElement[] trace = ex.getStackTrace();
for (int i = 0; i < trace.length && i < 15; i++)
StackTraceElement s = trace[i];
sOut.append("\\tat " + s + "\\r\\n");
return sOut.toString();
以上是关于Springboot捕获全局异常404-NoHandlerFoundException及Swagger/静态路由处理的主要内容,如果未能解决你的问题,请参考以下文章