Использование унифицированной схемы обработки ошибок Spring boot/Spring

Spring Boot задняя часть Spring переводчик
Использование унифицированной схемы обработки ошибок Spring boot/Spring

Например, когда мы разрабатываем весеннее веб-приложениеIOException,ClassNotFoundExceptionтаких как проверенные исключения, часто компилятор предлагает программисту использоватьtry-catchдля явного захвата, а для чего-то вродеClassCastException,NullPointerExceptionКомпилятор не будет запрашивать такие непроверенные исключения, что часто является аспектом способности программиста писать код.

В весенней сети, особенно в приложениях с весенней загрузкой, когда запрос успешно вызывается, он обычно возвращаетjsonОтформатируйте объект, как показано на следующем рисунке:

но если запрос выдаетRuntimeExceptionШерстяная ткань? Если мы этого не сделаем, при повторном вызове появится следующая страница:

То есть, когда в вызове возникает ошибка, spring-boot сопоставляет запрос с/errorЕсли нет соответствующего обработчика запроса пути, он вернет указанный вышеWhitelabelстраница ошибки.

1. Настройте страницу обработки ошибок

Конечно, невозможно не обрабатывать исключения во время выполнения! Обычной практикой является настройка единой страницы ошибок, а затем возврат. В соответствии с приведенной выше идеей мы реализуем путь запроса как/errorКонтроллер, контроллер возвращает адрес пути к ресурсу, который определяет путь отображения запроса как/errorконтроллер и реализацияErrorControllerинтерфейс, код выглядит следующим образом:

MyErrorPageController

package com.example.demo.controller.handler.errorpage;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 
 * The class MyErrorPageController.
 *
 * Description:自定义错误页面
 *
 * @author: huangjiawei
 * @since: 2018年6月13日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
@Controller
public class MyErrorPageController implements ErrorController {
    
    @RequestMapping("/error")
    public String handleError() {
    	return "error.html"; // 该资源位于resources/static目录下
    }
    
    @Override
    public String getErrorPath() {
    	return null;
    }
}

затем вreosurces/staticСоздано в каталогеerror.htmlдокумент:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>这是个错误页面!存放在resources/static目录下,spring-boot发生错误时默认调用</h1>
</body>
</html>

запросить сноваhttp://localhost:7000/demo/getUserInfoWithNoHandler.json,следующее:

2. Используйте@ControllerAdvice,@ResponseBody,@ExceptionHandlerУнифицированная обработка исключений

Весной для унифицированной обработки исключений можно использовать указанные выше три аннотации. По умолчанию мы можем определить унифицированный обработчик для определенного типа исключения в системе. Например, система выдаетNullPointerException, то мы можем определить специальныйNullPointerExceptionПроцессор, код такой:

getUserInfoWithNullPointerExceptionинтерфейс

/**
 * 测试空指针错误的处理
 * @return
 * @throws NullPointerException
 */
@RequestMapping(value = "getUserInfoWithNullPointerException.json", method = RequestMethod.GET)
public Student getUserInfoWithNullPointerException() throws NullPointerException {
	throw new NullPointerException();
}

NullPointerExceptionHandler.java

package com.example.demo.controller.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.pojo.ErrorReturn;

/**
 * 
 * The class NullPointerExceptionHandler.
 *
 * Description:处理空指针
 *
 * @author: huangjiawei
 * @since: 2018年6月13日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
@ControllerAdvice
public class NullPointerExceptionHandler {
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public ErrorReturn dealNullPointerException() {
        e.printStackTrace();
    	ErrorReturn error = new ErrorReturn();
    	error.setReturnCode("-1");
    	error.setDesc("出现空指针异常啦!");
    	return error;
    }
}

Браузерное исполнение:http://localhost:7000/demo/getUserInfoWithNullPointerException.json

По той же причине, если нам также необходимо предоставить унифицированный обработчик для других исключений времени выполнения, мы также можем определить обработчик для каждого типа исключения, как указано выше.Например, мы хотимArithmeticExceptionОпределяем процессор, далее нам нужно только создать класс или метод, а потом на метод@ExceptionHanlerдобавить в комментарийArithmeticException.classПросто укажите тип исключения.

Но обнаружили ли вы, что класс или метод обработки исключений определяется таким образом для каждого типа исключений, поскольку во время выполнения существует так много типов исключений, что невозможно указать класс или метод обработчика для каждого типа. также может быть решен. Если у нас нет исключения для определенного типа, напримерArithmeticExceptionопределить процессор, то мы можем определитьExceptionилиThrowableУнифицированная обработка процессора.

Преимущество этого в том, что он уменьшает количество классов-обработчиков и передает обработку исключений родительскому классу, что также является большим преимуществом наследования! Однако, когда вы определяете как конкретный тип исключения, так иExceptionобработчик исключений, то будьте осторожны, здесь не обязательно отношение приоритета, то есть не может быть ситуации, когда выполняется только родительский обработчик исключений, это может быть только обработчик A, а не обработчик B, или Выполняется только процессор B, а процессор A не выполняется. какNullPointerExceptionHandlerисключение будетExceptionпередача исключения (ноArithmeticExceptionнеExceptionперечислить)

Теперь предположим, что мы оба определяем приведенное вышеNullPointerExceptionHandler, который определяет следующееExceptionThrowableHandler, то когда это произойдетNullPointerExceptionвыполняется по умолчаниюExceptionThrowableHandlerМетоды.

ExceptionThrowableHandler.java

package com.example.demo.controller.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.pojo.ErrorReturn;

/**
 * 
 * The class ExceptionThrowableHandler.
 *
 * Description:有些异常会向高级别异常传递(但ArithmeticException不会向Exception传送)
 *
 * @author: huangjiawei
 * @since: 2018年6月13日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
@ControllerAdvice
public class ExceptionThrowableHandler {
    
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public ErrorReturn dealThrowable() {
    	ErrorReturn error = new ErrorReturn();
    	error.setDesc("处理Throwable!");
    	error.setReturnCode("-1");
    	return error;
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ErrorReturn dealCommonException() {
    	ErrorReturn error = new ErrorReturn();
    	error.setReturnCode("-1");
    	error.setDesc("公共异常处理!");
    	return error;
    }
}

Браузерное исполнение:http://localhost:7000/demo/getUserInfoWithNullPointerException.json

можно найти только для выполненияExceptionПроцессор, который не выполняет нулевой указатель, то есть обработка исключений передается вверх. Давайте посмотрим на бросокArithmeticExceptionСлучай:

getUserInfoWithArithmeticException.json

/**
 * 测试ArithmeticException错误的处理
 * @return
 * @throws ArithmeticException
 */
@RequestMapping(value = "getUserInfoWithArithmeticException.json", method = RequestMethod.GET)
public Student getUserInfoWithArithmeticException() throws ArithmeticException {
	throw new ArithmeticException();
}

ArithmeticExceptionHandler.java

package com.example.demo.controller.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.pojo.ErrorReturn;

@ControllerAdvice
public class ArithmeticExceptionHandler {
    /**
     * 处理ArithmeticException异常
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ArithmeticException.class)
    public ErrorReturn dealArithmeticException() {
    	ErrorReturn errorObject = new ErrorReturn();
    	errorObject.setReturnCode("-1");
    	errorObject.setDesc("算数处理出现异常!");
    	return errorObject;
    }
}

Браузерное исполнение:http://localhost:7000/demo/getUserInfoWithArithmeticException.json

Получается, что обработка исключений не идет на верхний уровеньExceptionHandlerОтправить.

Резюме: Для процессоров, которые определяют определенный тип и определяютExceptionБудьте особенно осторожны при ожидании процессоров супертипа, не все исключения будут обрабатываться на верхнем уровне, если мы хотим уменьшить количество только классов процессора, а не хотим добавлять классы или методы для каждого конкретного типа процессора, то Редактор рекомендует использоватьinstanceofКлючевое слово может использоваться для оценки типа исключения.

Как и в следующем коде, мы создаем общедоступный обработчик исключений только для обработкиExceptionисключение при использованииinstanceofвынести приговор.

@ExceptionHandler(Exception.class)
@ResponseBody
public ErrorReturn dealCommonException(Exception e) {
    ErrorReturn error = new ErrorReturn();
    // 此处可以采用 instanceof 判断异常类型
    if (e instanceof ArithmeticException) {
    	error.setReturnCode("-1");
    	error.setDesc("算数异常处理!");
    	return error;
    }
    System.err.println("exception");
    error.setReturnCode("-1");
    error.setDesc("公共异常处理!");
    return error;
}

Броски выполнения браузераArithmeticExceptionинтерфейс следующим образом:

Кодовый адрес этой статьи:GitHub.com/smallercode…

Спасибо за прочтение, добро пожаловать, поправьте меня!