В реальной разработке мы столкнемся со многими исключениями.Когда возникает исключение, Spring Boot предоставляет страницу ошибки для отображения пользователю по умолчанию. Выглядит дружелюбно, но на самом деле страница уродлива.
Выше было о проблемах, возникающих при разработке страницы.Другая ситуация - разработка интерфейса Rest.При возникновении ошибки мы хотим вернуть пользователю стандартный формат нашего интерфейса, а не вернуть кусок html кода.
Далее мы представим вам решения:
обработка страницы
Прежде всего, давайте посмотрим на обработку ошибок страницы, Когда наша программа сообщает об ошибке или посещенная страница не может быть найдена, мы можем увидеть следующую страницу ошибки:
Мы можем создать более красивую страницу, чтобы заменить эту страницу, которая будет более дружественной.Например, мы смотрим на страницу Toutiao:
В прошлом при использовании Spring MVC файл web.xml настраивался напрямую.
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/404.jsp</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/WEB-INF/view/400.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/view/500.jsp</location>
</error-page>
В Spring Boot это также очень просто: вы можете напрямую написать соответствующую страницу ошибки и перезаписать ее:
/**
* 自定义错误页面覆盖spring boot中的错误页面
* @author yinjihuan
*
*/
@Controller
public class ErrorController {
@GetMapping("/400")
public String badRequest() {
return "error/400";
}
@GetMapping("/404")
public String notFound() {
return "error/404";
}
@GetMapping("/500")
public String serverError() {
return "error/500";
}
}
Содержимое страницы можно написать самостоятельно:
<body>
<section id="error" class="container text-center" style="height:800px;">
<h1>404, 页面没有找到</h1>
<p>您正在寻找的页面不存在或发生其他错误。</p>
<a class="btn btn-primary" href="http://pan.cxytiandi.com">回到网站首页</a>
</section>
</body>
Работа с REST-интерфейсом
При разработке интерфейса для отдыха мы часто определяем унифицированный формат возврата, например:
{
"status": true,
"code": 200,
"message": null,
"data": [
{
"id": "101",
"name": "jack"
},
{
"id": "102",
"name": "jason"
}
]
}
Но если звонящий напишет неправильный адрес интерфейса при запросе нашего API, он получит страницу с ошибкой 404. Самый дружелюбный способ — вернуть фиксированный формат JSON с кодом 404.
Поэтому нам нужно иметь возможность возвращать наш пользовательский формат при возникновении этой системной ошибки.
Определите класс обработки исключений
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 系统异常处理,比如:404,500
* @param req
* @param resp
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseData defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
logger.error("", e);
ResponseData r = new ResponseData();
r.setMessage(e.getMessage());
if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
r.setCode(404);
} else {
r.setCode(500);
}
r.setData(null);
r.setStatus(false);
return r;
}
}
Ответы нашего возврата формируют классы сущности
public class ResponseData {
private Boolean status = true;
private int code = 200;
private String message;
private Object data;
}
Это будет захвачено здесь при возникновении ошибки, а затем инкапсулировано в формате возврата и возвращено вызывающей стороне.
Последний ключевой шаг — добавить следующую конфигурацию в файл конфигурации весенней загрузки:
#出现错误时, 直接抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
#不要为我们工程中的资源文件建立映射
spring.resources.add-mappings=false
Затем, когда мы вызываем несуществующий интерфейс, возвращается сообщение об ошибке в формате, который мы настроили.
{
"status": false,
"code": 404,
"message": "No handler found for GET /rest11/auth",
"data": null
}
Ошибки страницы и ошибки REST сосуществуют
Когда мы добавим метод обработки интерфейса rest, часть данных json будет возвращена, если страница доступа не существует.Если в вашем проекте есть и интерфейс rest, и страница, в это время будет конфликт.
Мы можем добавить префикс унифицированного доступа для интерфейса отдыха, например: / RECT / XXXX, чтобы отличить запрос, затем использовать @controllerAdvice для обработки:
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 系统异常处理,比如:404,500
*
* @param req
* @param resp
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
// @ResponseBody
public Object defaultErrorHandler(HttpServletRequest req, HttpServletResponse response, Exception e)
throws Exception {
logger.error("", e);
if (req.getRequestURI().startsWith("/rest")) {
ResponseData r = new ResponseData();
r.setMessage(e.getMessage());
if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
r.setCode(404);
} else {
r.setCode(500);
}
r.setData(null);
r.setStatus(false);
PrintWriter writer = response.getWriter();
writer.println(JsonUtils.toJson(r));
writer.flush();
writer.close();
return null;
} else {
if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
return "error/404";
} else {
return "error/500";
}
}
}
}
Для большего обмена технологиями, пожалуйста, обратите внимание на общедоступную учетную запись WeChat: Yuantiandi