项目在运行的时候一般不会直接把错误页面返回给用户,否则,用户体验极差:
springmvc可以实现一个全局异常拦截,如果服务器抛出异常,则将异常进行封装一下,返回给前端处理,一般是返回json数据如图:
这样的话用户体验感会好一点:我自己写的一个全局异常
第一种是实现HandlerExceptionResolver接口重写方法resolveException返回modelandView对象:(不推荐)
@Component
public class GlobalHandlerExceptionResolver implements HandlerExceptionResolver {
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("进入全局异常");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject(new HashMap());
return modelAndView;
}
}
第一种是继承ResponseEntityExceptionHandler抽象类通过注解写方法@ExceptionHandler({Exception.class}):(不推荐继承,不符合java核心思想)
@ControllerAdvice
public class GlobalHandlerExceptionResolver extends ResponseEntityExceptionHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* 数据找不到异常
* @param ex
* @param request
* @return
* @throws IOException
*/
@ExceptionHandler({Exception.class})
public ResponseEntity<Object> handleDataNotFoundException(RuntimeException ex, WebRequest request) throws IOException {
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
我们看看ResponseEntityExceptionHandler类的源码:
发现这个类其实就是springmvc自己的异常处理类,他封装了springmvc处理请求时可能抛出的异常,比较常见的就是没有找到对应的url路径:就会404
No mapping found for HTTP request with URI [/] in DispatcherServlet with name 'SpringMVC'
我们也可以重写对应的方法来修改springmvc自己在处理的时候抛出的异常;
最后说我个人比较推荐的方式,其实跟第二种差不多(不多说):
@EnableWebMvc
@ControllerAdvice
public class BaseExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(BaseExceptionHandler.class);
@ResponseBody
@ExceptionHandler(NoHandlerFoundException.class)
public BaseResponse handleNoHandlerFoundException(NoHandlerFoundException ex, HttpServletRequest request) {
logger.error(String.format("请求方法[%s]发生异常,错误信息:[%s]",
request.getRequestURI(), ex.getMessage()), ex);
return BaseResponse.fail(ErrorCodeEnum.NO_HANDLE_PAGE);
}
@ResponseBody
@ExceptionHandler(TypeMismatchException.class)
public BaseResponse handleTypeMismatchException(TypeMismatchException ex) {
return BaseResponse.fail(ErrorCodeEnum.PARARMA_MISMATCH);
}
@ResponseBody
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public BaseResponse handleTypeNotSupportException(HttpMediaTypeNotSupportedException ex) {
return BaseResponse.fail(ErrorCodeEnum.PARARMA_NOTSUPPORT.getCode(),
String.format(ErrorCodeEnum.PARARMA_NOTSUPPORT.getMsg(), ex.getContentType(),
Arrays.toString(ex.getSupportedMediaTypes().toArray())));
}
@ResponseBody
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public BaseResponse handleMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
return BaseResponse.fail(ErrorCodeEnum.METHOD_NOTSUPPORT.getCode(),
String.format(ErrorCodeEnum.METHOD_NOTSUPPORT.getMsg(), ex.getMethod(),
Arrays.toString(ex.getSupportedMethods())));
}
/**
* 处理参数错误的异常
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler(IllegalParamsException.class)
public BaseResponse handleArgumentException(IllegalParamsException ex) {
return BaseResponse.fail(ErrorCodeEnum.ILLEGE_PARAMS.getCode(), ex.getMessage());
}
/**
* 处理未登录或登录过期的异常
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(UnLoginException.class)
public BaseResponse handleTokenOverdueException(UnLoginException ex) {
return BaseResponse.fail(ErrorCodeEnum.NO_LOGIN);
}
@ResponseBody
@ExceptionHandler(BaseException.class)
public BaseResponse handleBaseException(BaseException ex, HttpServletRequest request) {
logger.error(String.format("请求方法[%s]发生异常,[错误代码:%s,错误信息:%s]",
request.getRequestURI(), ex.getCode(), ex.getMessage()));
return BaseResponse.fail(ex.getCode(), ex.getMessage());
}
@ResponseBody
@ExceptionHandler(RuntimeException.class)
public BaseResponse handleUnexpectedServerError(RuntimeException ex, HttpServletRequest request) {
logger.error(String.format("请求方法[%s]发生异常,错误信息:[%s]",
request.getRequestURI(), ex.getMessage()), ex);
return BaseResponse.fail(ErrorCodeEnum.SERVER_ERROR);
}
@ResponseBody
@ExceptionHandler(Exception.class)
public BaseResponse defaultErrorHandler(HttpServletRequest request,Exception ex ) {
logger.error(String.format("请求方法[%s]发生异常,错误信息:[%s]",
request.getRequestURI(), ex.getMessage()), ex);
return BaseResponse.fail(null, ex.getMessage());
}
}