项目1在线交流平台-3.开发交流社区核心功能模块-9.AOP编程-统一处理异常

参考牛客网高级项目教程

功能需求及处理策略

在这里插入图片描述

  • 统一处理表现层的异常
    • 因为,数据层、业务层均会将异常往上抛,最终都会抛给表现层
  • 采取的策略是:面向切面编程,使用Spring的注解,统一管理bean中的异常,
    • 无需在每个Controller中定义处理

2. SpringBoot快速处理错误页面

在这里插入图片描述
  • 在SpringBoot中,只需将错误页面放在指定路径下,特定命名的文件夹下,出现异常会自动访问这些页面

    • 指定路径:classPath根目录下的templates路径下
    • 指定文件名:error
  • 原理应是框架内部设置了默认的处理路径

  • 测试:

    • 404错误

      在这里插入图片描述
    • 500错误

      /** 会话列表显示 */
      @RequestMapping(path = "/letter/list", method = RequestMethod.GET)
      public String getLetterList(Model model, Page page) {
          Integer.valueOf("abf");
          ...
      
      在这里插入图片描述

3. Spring使用注解统一处理异常

  • 对于404错误,直接返回一个提示页面是可以的
  • 但对于500错误,除了要返回错误页面,还要对错误信息进行日记记录处理等
  • 因此,需要用到Spring的注解统一处理异常

@ControllerAdvice

  • 用于修饰类,表示该类是Controller的全局配置类。

    • 可以指定扫描的组件,一般就是Controller组件
  • 在此类中,可以对Controller进行如下三种全局配置:

    • 异常处理方案:@ExceptionHandler
    • 绑定数据方案:@ModelAttribute
    • 绑定参数方案:@DataBinder
    package com.nowcoder.community.controller.advice;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    
    @ControllerAdvice(annotations = Controller.class)
    public class ExceptionAdvice {
        
    }
    
@ExceptionHandler
  • 用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
request.getHeader(“x-requested-with”)
  • 可以获取请求的方式
    • 是普通的网页请求:HttpRequest
    • 还是异步请求:XMLHttpRequest
XMLHttpRequest
  • 设置返回的类型:

    • 普通的字符串格式:"application/plain

      • 向浏览器返回一个字符串,需手动转换为js对象

        // 将返回的字符串转为json对象,方便调用
        data = $.parseJSON(data);
        
    • Json格式 :"application/json

      • 向浏览器返回一个字符串,浏览器会自动转换为Js对象
    response.setContentType("application/plain;charset=utf-8");
    
@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {
    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);
    @ExceptionHandler({Exception.class})
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException, IOException {
        logger.error("服务器发生异常: " + e.getMessage());
        // 遍历栈的信息
        for(StackTraceElement element : e.getStackTrace()) {
            logger.error(element.toString());
        }

        // 重定向错误页面,但有可能是异步请求,否则返回到json
        String xRequestedWith = request.getHeader("x-requested-with");
        if(xRequestedWith.equals("XMLHttpRequest")) {
            response.setContentType("application/plain;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));
        } else {
            response.sendRedirect(request.getContextPath() + "/error");
        }
    }
}
@ModelAttribute
  • 用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定数据参数
    • 可以往model中绑定统一的参数数据,给所有controller用
@DataBinder
  • 用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器
    • 页面传参,会自动转换为请求方法中接收的参数,框架中有定义好的转换器
    • 如果页面传入了特殊的参数,框架中定义好的转换器不可用,可以自定义转换器注册上

测试

  • 普通请求错误

    /** 会话列表显示 */
    @RequestMapping(path = "/letter/list", method = RequestMethod.GET)
    public String getLetterList(Model model, Page page) {
        // 添加一个错误,进行测试
        Integer.valueOf("abf");
        ...
    

    在这里插入图片描述
    在这里插入图片描述

  • 异步请求错误

    /**
     * 处理ajax异步发布帖子请求
     * @param title     帖子主题
     * @param content   帖子内容
     * @return          JSON字符串
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public String addPost(String title, String content) {
        // 添加一个错误,进行测试
        Integer.valueOf("add");
        ...
    

    在这里插入图片描述

    在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值