- Обработка исключений по умолчанию в Spring
- использовать
@ResponseStatus
Обработка пользовательских исключений - использовать
try {…} catch
Перехватывать исключения вручную - использовать
@ExceptionHandler
Обработка пользовательских исключений - использовать
@ControllerAdvice
Аннотация обрабатывает все исключения - Суммировать
- Ссылаться на
Обработка исключений по умолчанию в Spring
В Spring некоторые исключения по умолчанию сопоставляются с кодами состояния HTTP и не требуют программной обработки. В следующей таблице перечислены способы обработки исключений в Spring по умолчанию:
Весеннее исключение | Коды состояния HTTP |
---|---|
BindException | 400 - Bad Request |
ConversionNotSupportedException | 500 - Internal Server Error |
HttpMediaTypeNotAcceptableException | 406 - Not Acceptable |
HttpMediaTypeNotSupportedException | 415 - Unsupported Media Type |
HttpMessageNotReadableException | 400 - Bad Request |
HttpMessageNotWritableException | 500 - Internal Server Error |
HttpRequestMethodNotSupportedException | 405 - Method Not Allowed |
MethodArgumentNotValidException | 400 - Bad Request |
MissingServletRequestParameterException | 400 - Bad Request |
MissingServletRequestPartException | 400 - Bad Request |
NoSuchRequestHandlingMethodException | 404 - Not Found |
TypeMismatchException | 400 - Bad Request |
Исключения в приведенной выше таблице генерируются самой Spring, еслиDispatcherServlet
Возвращает напрямую, когда возникает проблема во время обработки или при выполнении проверки. Например, еслиDispatcherServlet
Невозможно найти подходящий метод контроллера для обработки запроса, выдастNoSuchRequestHandlingMethodException
Исключение, конечным результатом является ответ с кодом состояния 404 (не найдено).
использовать@ResponseStatus
Обработка пользовательских исключений
Но он не может обрабатывать пользовательские исключения, создаваемые внутри приложения. Например, в службе выдается пользовательское исключение (NullOrgException
),МыNullOrgException
Добавлено исключение@ResponseStatus
Аннотация, вы можете присвоить ей код состояния.
Например, следующий код:
package com.rebecca.springmvc.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* 自定义异常
* @Author: Rebecca
* @Description:
* @Date: Created in 2019/6/14 17:04
* @Modified By:
*/
@ResponseStatus(value = HttpStatus.NO_CONTENT, reason = "No Content")
public class NullOrgException extends RuntimeException {
}
использоватьtry {…} catch
Перехватывать исключения вручную
После определения вышеупомянутого исключения, пока в приложении есть бросокNullOrgException
Исключения перехватываются и сопоставляются с соответствующими кодами состояния. Что делать, если программе нужен не только код состояния, но и сгенерированная ошибка? На данный момент мы больше не можем обрабатывать исключения как ошибки HTTP, а обрабатывать исключения так же, как мы обрабатываем запросы.
package com.rebecca.springmvc.controller.exception;
import com.rebecca.springmvc.org.bean.Org;
import com.rebecca.springmvc.org.service.OrgService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("test/exception")
public class ExceptionTestController {
private Logger logger = LoggerFactory.getLogger(ExceptionTestController.class);
@Autowired
private OrgService service;
@RequestMapping(value = "orgs", method = RequestMethod.GET)
@ResponseBody
public List<Org> getOrgs () {
List<Org> orgs = null;
try {
orgs = service.getOrgs();
} catch (NullOrgException e) {
logger.error("无组织机构相关数据!",e);
}
return orgs;
}
}
Например, в коде вышеNullOrgException
Исключение, в Spring нет сопоставления по умолчанию, самый простой способ -try {…} catch (NullOrgException e) {…}
.
использовать@ExceptionHandler
Обработка пользовательских исключений
вышесказанноеtry {…} catch
Этот метод не способствует сопровождению кода, к счастью, Spring предоставляет механизм, который можно использовать.@ExceptionHandler
Аннотации сопоставляют исключения с кодами состояния HTTP. Ниже приведено использование@ExceptionHandler
Аннотированный способ:
package com.rebecca.springmvc.controller.exception;
import com.rebecca.springmvc.org.bean.Org;
import com.rebecca.springmvc.org.service.OrgService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("test/exception")
public class ExceptionTestController {
private Logger logger = LoggerFactory.getLogger(ExceptionTestController.class);
@Autowired
private OrgService service;
@RequestMapping(value = "orgs", method = RequestMethod.GET)
@ResponseBody
public List<Org> getOrgs () {
List<Org> orgs = service.getOrgs();
return orgs;
}
@ExceptionHandler(NullOrgException.class)
public String handleNullOrgException() {
return "无组织机构相关数据!";
}
}
В приведенном выше коде мыhandleNullOrgException()
добавлен метод@ExceptionHandler
аннотацию, когда программа выбрасываетNullOrgException
Когда возникает исключение, этот метод будет делегирован для обработки. Его возвращаемое значение — String, вы также можете изменить его на другие типы возвращаемых значений в соответствии с потребностями приложения. для использования@ExceptionHandler
Для методов, аннотированных аннотациями, он может обрабатывать исключения, создаваемые всеми методами-обработчиками в одном и том же контроллере (контроллере).
Чтобы избежать записи дубликатов в нескольких контроллерах@ExceptionHandler
Annotation, мы создадим базовый класс контроллера, все классы контроллера должны расширять этот класс, поэтомунаследоватьуниверсальный@ExceptionHandler
метод.
использовать@ControllerAdvice
Аннотация обрабатывает все исключения
Ранее мы говорили использовать@ExceptionHandler
Аннотации могут обрабатывать только исключения, генерируемые всеми методами обработчика в контроллере (контроллере), поэтому есть ли способ обрабатывать исключения, генерируемые методами обработчика во всех контроллерах, без интеграции?
Ответ: да! Начиная с Spring 3.2 это определенно возможно, нам просто нужно определить это в классе уведомлений контроллера.
После Spring 3.2 для такого рода проблем было введено новое решение: совет контроллера.
Совет диспетчера относится к любому@ControllerAdvice
Аннотированный класс.
Этот класс будет содержать один или несколько из следующих типов методов:
-
@ExceptionHandler
Аннотационный метод аннотации; -
@InitBinder
Аннотационный метод аннотации; -
@ModelAttribute
Аннотационный метод аннотации.
в с@ControllerAdvice
В аннотированном классе вышеуказанные методы будут применяться ко всем контроллерам с@RequestMapping
по методу аннотации.@ControllerAdvice
Сама аннотация уже используется@Component
,следовательно@ControllerAdvice
Класс, отмеченный аннотацией, будет автоматически получен при сканировании компонента, и есть@Component
Аннотированные классы одинаковы.@ControllerAdvice
Один из наиболее практичных сценариев — объединить все@ExceptionHandler
Методы собраны в класс, чтобы исключения от всех контроллеров можно было обрабатывать единообразно в одном месте. Например, мы хотимNullOrgException
Метод обработчика используется на всех контроллерах во всем приложении. Следующий листинг программы показываетAppWideExceptionHandler
может выполнить эту задачу, это@ControllerAdvice
Аннотированный класс. Используйте следующий код@ControllerAdvice
, для обработки исключений для всех контроллеров:
package com.rebecca.springmvc.controller.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
/**
* 控制器通知类
* @Author: Rebecca
* @Description:
* @Date: Created in 2019/6/14 16:30
* @Modified By:
*/
@ControllerAdvice // 定义控制器类
public class AppWideException {
// 定义异常处理方法
@ExceptionHandler(NullOrgException.class)
public String handleNullOrgException() {
return "无组织机构相关数据!";
}
}
Теперь, если какой-либо метод контроллера выдает исключение DuplicateSpittleException, для обработки исключения будет вызываться метод DuplicateSpittleHandler() независимо от того, в каком контроллере находится этот метод. Мы можем писать аннотированные методы @ExceptionHandler так же, как мы пишем аннотированные методы @RequestMapping. Как показано в листинге 7.10, он возвращает "error/duplicate" в качестве имени логического представления, поэтому пользователю будет представлена удобная страница с ошибкой.
Суммировать
Обработка исключений в Spring:
- Определенные исключения Spring будут автоматически сопоставлены с указанными кодами состояния HTTP;
-
аномальныйможно добавить на
@ResponseStatus
Аннотация для сопоставления с кодом состояния HTTP; - существуетметодможно добавить на
@ExceptionHandler
Аннотация, чтобы ее можно было использовать для обработки исключений. - будет
@ExceptionHandler
Аннотированный метод исключения извлекается в@ControllerAdvice
В аннотированном классе действует все приложение (этот метод применим только к Spring 3.2+).
Самый простой способ обработки исключений — сопоставить их с кодами состояния HTTP и поместить в ответ.
Ссылаться на
«Весна в действии, 4-е издание»