说明
我们博客前台的功能现在已经算是做完了,我们这个时候来把异常这里说下,我们之前在写后端时捕获过一次异常,但我们直接返回了一个json
,这样明显是不合理的,因我们我们的路由有些是页面,有些是json
,我们只需要在接口返回值是json
的时候才返回json
,其它情况我们希望返回页面
定义异常页面
我们在定义异常页面时可以先将error.html
重命名为fail.html
,因为Thymeleaf
在解析模板出错时会自动跳转到error.html
- 我们定义一个枚举为
ErrorCode
,来存放我们的HTTP
状态码和对应的信息
package cn.kevinlu98.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Author: Mr丶冷文
* Date: 2022/10/15 19:40
* Email: kevinlu98@qq.com
* Description:
*/
@Getter
@AllArgsConstructor
public enum ErrorCodeEnum {
ERROR_404(404,"对不起,你请求的页面暂时未找到.<br>它或许已经被迁移至其它页面啦."),
ERROR_500(500,"您好,服务器暂时出发问题,请稍候访问.<br>或您也可以尝试联系站长."),
;
private final int code;
private final String msg;
}
- 然后定义
404
和500
的路由
@GetMapping("/error/404")
public String error404(Model model) {
model.addAttribute("error", ErrorCodeEnum.ERROR_404);
return "fail";
}
@GetMapping("/error/500")
public String error500(Model model) {
model.addAttribute("error", ErrorCodeEnum.ERROR_500);
return "fail";
}
错误页面配置
重要:大家先要明白一件事件,就是我们的错误页面配置是根据HTTP请求返回的状态码决定的,这个与统一异常处理不一样
- 我们在
config
里面给Spring
容器一个类型为WebServerFactoryCustomizer
泛型为ConfigurableWebServerFactory
的bean
- 在这个
bean
里我们去调用addErrorPages
的方法指定HTTP状态对应的路由
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
return factory -> factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"), new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
}
统一异常改造
我们之前已经做过了统一异常处理,但这个处理是非常不科学的,它不论什么样的情况都会返回一个json
,这让用户在访问我们的网站时的交互就显得不是那么友好,因为用户访问的只会是前台页面
我们可以在发生异常时判断一个请求的后缀,因为当时我们在开发项目定义路由时我们所有页面的返回都是以.html
结尾的,那我们就可以认为只要是以.html
结尾的请求都是页面,这个时候我们就可以返回到错误页面,反之我们返回一个json
这个时候我们又有问题了,我们返回页面和返回json
的返回值不同,我们应该怎么处理呢?那我们可以直接让返回值为void
,不让springboot
帮我们返回,我们自己利用Servlet
的接口进行返回就可以了
@ExceptionHandler(Exception.class)
public void defaultException(Exception e, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
e.printStackTrace();
log.error(e.getMessage(), e);
if (request.getRequestURI().endsWith(".html")) {
request.getRequestDispatcher("/error/500.html").forward(request, response);
} else {
response.setCharacterEncoding("utf-8");
response.getWriter().print(new ObjectMapper().writeValueAsString(Result.error()));
}
}
自定义异常
我们可以看到当我们访问一个不存在的文章时由于错误码是500,此时会被我们配置的错误页面拦截,但按照逻辑来讲这个时候应该是一个文章不存在,在业务上属于404,我们可以自定义一个异常,然后在统一异常里面捕获这个异常,给其重定向到404页面
@ExceptionHandler(LWNotFindException.class)
public String notFindException(LWNotFindException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
return "forward:/error/404.html";
}
谢谢分享
没看见下载
螃蟹分享
谢谢分享
好耶