Spring Boot 2.X (11): глобальная обработка исключений

Spring Boot

предисловие

При разработке веб-системы Java, будь то уровень контроллера, уровень сервиса или уровень Dao, могут возникать исключения. Если вы добавите к каждому методу различный код обработки исключений try catch, это сделает код очень громоздким. В Spring MVC мы можем отделить все типы обработки исключений от отдельных методов для унифицированной обработки и обслуживания информации об исключениях.

Обычно существует два решения для глобальной обработки захвата исключений в Spring MVC:

1. Используйте аннотацию @ControllerAdvice + @ExceptionHandler для обработки исключений на глобальном уровне контроллера.

2. Реализуйте метод resolveException в интерфейсе org.springframework.webb.servlet.HandlerExceptionResolver.

Аннотировать с помощью @ControllerAdvice + @ExceptionHandler

1. Определите унифицированный класс обработки исключений

@ControllerAdvice
public class GlobalExceptionHandler {

	private Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@ExceptionHandler(value = Exception.class)
	public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) {
		log.error("ExceptionHandler ===>" + e.getMessage());
		e.printStackTrace();
		// 这里可根据不同异常引起的类做不同处理方式
		String exceptionName = ClassUtils.getShortName(e.getClass());
		log.error("ExceptionHandler ===>" + exceptionName);
		ModelAndView mav = new ModelAndView();
		mav.addObject("stackTrace", e.getStackTrace());
		mav.addObject("errorMessage", e.getMessage());
		mav.addObject("url", req.getRequestURL());
		mav.setViewName("forward:/error/500");
		return mav;
	}
}

Где @ExceptionHandler (значение = Exception.class) захватывает ненормальное значение, может быть настроен следующим образом:

тип описывать
NullPointerException Это исключение возникает, когда приложение пытается получить доступ к пустому объекту.
SQLException Исключения, которые предоставляют информацию об ошибках доступа к базе данных или других ошибках
IndexOutOfBoundsException Возникает, когда индекс сортировки (например, сортировка массива, строки или вектора) выходит за пределы
NumberFormatException Генерируется, когда приложение пытается преобразовать строку в числовой тип, но строку не удается преобразовать в правильный формат.
FileNotFoundException Это исключение возникает, когда попытка открыть файл, представленный указанным путем, не удалась.
IOException Это исключение возникает, когда возникает какое-либо исключение ввода-вывода. Этот класс является общим классом для исключений, генерируемых неудачными или прерванными операциями ввода-вывода.
ClassCastException Выбрасывается при попытке привести объект к подклассу, который не является экземпляром
ArrayStoreException Возникает исключение при попытке сохранить объект неправильного типа в массиве объектов
IllegalArgumentException Возникшее исключение указывает на то, что методу был передан недопустимый или неверный параметр.
ArithmeticException Это исключение выдается при возникновении нештатных условий работы. Например, экземпляр этого класса выбрасывается, когда целое число «делится на ноль».
NegativeArraySizeException Возникает, если приложение пытается создать массив отрицательного размера.
NoSuchMethodException Это исключение возникает, когда определенный метод не может быть найден
SecurityException Исключение, созданное менеджером безопасности, указывает на нарушение безопасности
UnsupportedOperationException Это исключение возникает, когда запрошенная операция не поддерживается
RuntimeException это суперкласс исключений, которые могут быть вызваны во время нормальной работы виртуальной машины Java.

Когда тип исключения ответа перехвачен, он войдет в логику метода defaultErrorHandler(): поместит информацию об исключении в модель и перейдет к URL-адресу запроса /error/500.

2. Отображение ненормальной информации

Просмотр конфигурации контроллера

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

	/**
	 * 视图控制器配置
	 */
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {	
		registry.addViewController("/").setViewName("/index");//设置默认跳转视图为 /index
		registry.addViewController("/error/500").setViewName("/error/500");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
        super.addViewControllers(registry);
		
	}
	
}

шаблон просмотра

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Exception</h1>
<h3 th:text="${url}"></h3>
<h3 th:text="${errorMessage}"></h3>
<p  th:each="line : ${stackTrace}" th:text="${line}">  </p>
</body>
</html>

3. Тестовый класс исключений

@Controller
public class TestController {

	@GetMapping("/index")
	public String hello() {
		int x = 1 / 0;
		return "hello";
	}
}

4. Запустите тест

Доступ через браузер:http://127.0.0.1:8080/index

@ControllerAdvice также можно использовать в сочетании с аннотациями @ModelAttribute и @InitBinder для реализации таких функций, как привязка глобальных данных и предварительная обработка глобальных данных.

Реализовать интерфейс HandlerExceptionResolver

1. Определите унифицированный класс обработки исключений

@Component
public class GlobalHandlerExceptionResolver implements HandlerExceptionResolver {

	private Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		Exception e = new Exception();
		//处理 UndeclaredThrowableException
		if (ex instanceof UndeclaredThrowableException) {
			e = (Exception) ((UndeclaredThrowableException) ex).getUndeclaredThrowable();
		} else {
			e = ex;
		}
		e.printStackTrace();
		//这里可以根据不同异常引起的类做不同处理方式
		String exceptionName = ClassUtils.getShortName(e.getClass());
		if(exceptionName.equals("ArrayIndexOutOfBoundsException")) {
			log.error("GlobalHandlerExceptionResolver resolveException ===>" + exceptionName);
			ModelAndView mav = new ModelAndView();
			mav.addObject("stackTrace", e.getStackTrace());
			mav.addObject("exceptionName", exceptionName);
			mav.addObject("errorMessage", e.getMessage());
			mav.addObject("url", request.getRequestURL());
			mav.setViewName("forward:/error/500");
			return mav;
		}
		return null;
	}

}

Исключение UndeclaredThrowableException обычно возникает при вызове интерфейса RPC или при использовании динамического прокси-сервера JDK. Без предварительной обработки преобразования исключение, перехватываемое тестом, является UndeclaredThrowableException, а не фактическим объектом исключения.

2. Отображение ненормальной информации То же, что и выше

3. Тестовый класс исключений

@Controller
public class TestController {

	@GetMapping("/test")
	public String test() {
		String[] ss = new String[] { "1", "2" };
		System.out.print(ss[2]);
		return "hello";
	}

}

4. Пробный запуск

Аннотируйте @ControllerAdvice перед тестированием. Доступ через браузер:http://127.0.0.1:8080/test

образец кода

github

Облако кода

Если не указано иное, авторские права на эту статью принадлежатутренний туманВсе, пожалуйста, указывайте источник при перепечатке.

Оригинальное название: Spring Boot 2.X (11): глобальная обработка исключений

Оригинальный адрес: https://www.zwqh.top/article/info/20

Если статья была вам полезна, отсканируйте код и подпишитесь на мой официальный аккаунт, статья постоянно обновляется...