Mr丶冷文

文章 分类 评论
115 10 5698

站点介绍

冷文学习者(KEVINLU98.COM),记录一个北漂小码农的日常业余生活
友链申请地址(直接评论即可): 传送门

(二十一)统一异常拦截及自定义错误跳转

MR丶冷文 2022-10-15 184 0条评论 个人博客项目视频教程 javaspringboot个人博客异常处理

首页 / 正文
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单

发布于2022-10-28

说明

我们博客前台的功能现在已经算是做完了,我们这个时候来把异常这里说下,我们之前在写后端时捕获过一次异常,但我们直接返回了一个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;
}
  • 然后定义404500的路由
@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泛型为ConfigurableWebServerFactorybean
  • 在这个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";
}

评论(0)

最新评论

  •  hh

  •  hh

  • 蝌蚪

    支持大佬

  • SURELY

    下载支持一下大佬

  • SURELY

    大佬支持啊,下载了试一下

日历

2022年12月

    123
45678910
11121314151617
18192021222324
25262728293031

文章目录

站点公告
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单
点击小铃铛关闭