3.31统一处理异常

之前讲过,服务端分为 表现层、业务层、数据层

浏览器发送的请求 一律发给 表现层,表现层调用业务层,业务层调用数据层。

数据层出问题,会抛出到上一层 业务层,业务层在往上抛给表现层。

所以三个层的异常最终都会 汇集到表现层。

因此,只要我们对 表现层 统一捕获异常,就能实现统一处理异常。

sping和spring boot都提供了 现成的方案来 对 表现层 统一捕获异常

将两个错误页面404和500 都放在error文件夹下,均置于templates下
在这里插入图片描述
没有 该路径
在这里插入图片描述
在这里插入图片描述
因为没有对404.html进行配置,因此出错。

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="stylesheet" th:href="@{/css/global.css}" />
<header class="bg-dark sticky-top" th:replace="index::header">
		<!-- 内容 -->
		<div class="main">
			<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
				<img th:src="@{/img/404.png}" >
			</div>
		</div>
<script th:src="@{/js/global.js}"></script>

刷新一下:
在这里插入图片描述
因为资源不存在,所以自动跳到404页面

即便是错误,也要给用户 清晰直观 友好的提示。

但是跳转页面只是表明,内在记录日志还没有处理。

在这里插入图片描述
接下来利用@ExceptionHandler对所有可能的异常进行处理

在HomeController里,配置 500.html的访问页面

@RequestMapping(path = "/error", method = RequestMethod.GET)
public String getErrorPage() {
    return "/error/500";
}

接下来利用@ControllerAdvice
声明 Controller的全局配置类,对所有Controller的异常做统一处理。

在Controller下新建advice包,在此包下新建ExceptionAdvice

package com.nowcoder.community.controller.advice;

import com.nowcoder.community.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@ControllerAdvice(annotations = Controller.class)//只扫描带有Controller注解的那些bean,进而统一处理
public class ExceptionAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);//实例化日志组件

    @ExceptionHandler({Exception.class})//用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {//Exception是controller中的异常
        logger.error("服务器发生异常: " + e.getMessage());
        for (StackTraceElement element : e.getStackTrace()) {//每一个element记录了一条错误信息,将其挨个记录
            logger.error(element.toString());
        }

        String xRequestedWith = request.getHeader("x-requested-with");//从请求的消息头里,尝试获取一个值(即请求的方式)
        if ("XMLHttpRequest".equals(xRequestedWith)) {//XML形式的请求,为异步请求,也可以返回json
            response.setContentType("application/plain;charset=utf-8");//plain表示向浏览器返回的是 普通字符串
            PrintWriter writer = response.getWriter();//获取输出流 以输出字符串
            writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));//报错类型是1
        } else {
            response.sendRedirect(request.getContextPath() + "/error");//否则是普通请求。重新定位到错误页面
        }
    }

}

于是可以实现统一处理异常,即不需要在任何一个Controller中加异常处理的代码

例如,故意写个错误,在这里写“abc”
在这里插入图片描述
访问首页
在这里插入图片描述
个人主页:还没有实现此功能
在这里插入图片描述
访问账号设置,也没问题
在这里插入图片描述
点击消息
在这里插入图片描述
在控制台 显示了err
在这里插入图片描述
去掉错误后 重新编译

可以 实现 消息
在这里插入图片描述
发私信时

在这里插入图片描述
点发送时
在这里插入图片描述
对应err级别日志
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值