项目在运行的时候一般不会直接把错误页面返回给用户,否则,用户体验极差:

springmvc可以实现一个全局异常拦截,如果服务器抛出异常,则将异常进行封装一下,返回给前端处理,一般是返回json数据如图:

springmvc全局异常处理_mvc


这样的话用户体验感会好一点:我自己写的一个全局异常

第一种是实现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全局异常处理_错误信息_02


发现这个类其实就是springmvc自己的异常处理类,他封装了springmvc处理请求时可能抛出的异常,比较常见的就是没有找到对应的url路径:就会404

No mapping found for HTTP request with URI [/] in DispatcherServlet with name 'SpringMVC'

springmvc全局异常处理_mvc_03


我们也可以重写对应的方法来修改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());
    }
	
	
}