美文网首页
springboot异常处理的基本规范

springboot异常处理的基本规范

作者: 平凡的柚子 | 来源:发表于2021-01-14 21:31 被阅读0次

    背景分析

    在项目的开发中,不管是对底层的数据逻辑操作过程,还是业务逻辑的处理过程,还是控制逻辑的处理过程,都不可避免会遇到各种可预知的、不可预知的异常。处理好异常对系统有很好的保护作用,同时会大大提高用户的体验。

    异常处理分析

    概述

    Java项目中处理异常方式无非两种,要么执行trycatch操作,要么执行throw操作(抛给其它对象处理),无论采用哪种方式,其目的是让我们的系统对异常要有反馈。但现在的问题是我们如何让这种反馈代码的编写即简单又直观、友好。

    处理规范

    我们在处理异常的过程中通常要遵循一定的设计规范,例如:

    捕获异常时与抛出的异常必须完全匹配,或者捕获异常是抛出异常的父类类型。
    避免直接抛出RuntimeException,更不允许抛出Exception或者Throwable,应使用有业务含义的自定义异常(例如ServiceException)。
    捕获异常后必须进行处理(例如记录日志)。如果不想处理它,需要将异常抛给它的调用者。
    最外层的逻辑必须处理异常,将其转化成用户可以理解的内容。
    避免出现重复的代码(Don't Repeat Yourself),即DAY原则。
    SpringBoot 工程下的异常处理

    准备工作

    第一步:创建项目或module,并添加web依赖,代码如下:

    <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

    第二步:修改项目访问端口为80,例如

    server.port=80
    

    第三步:定义Controller类,代码如下:

    package com.cy.pj.arithmetic.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class ArithmeticController {
    
     @RequestMapping("doCompute/{n1}/{n2}")
     @ResponseBody
     public String doCompute(@PathVariable Integer n1, 
     @PathVariable Integer n2){
      Integer result=n1/n2;
      return "Result is "+result;
     }
    }
    

    第四步启动项目进行访问测试

    在浏览器地址栏输入http://localhost/doCompute/10/2,检测输出结果。

    Result is 5

    默认异常处理

    在浏览器地址栏输入http://localhost/doCompute/10/0,检测输出结果。


    对于这样的默认异常处理(spring boot提供),用户体验不太友好,为了呈现更加友好的异常信息,我们通常要对异常进行自定义处理。

    自己try异常处理

    在控制层方法中,我们可以进行try catch处理,例如:

     @RequestMapping("doCompute/{n1}/{n2}")
     @ResponseBody
     public String doCompute(@PathVariable Integer n1, 
     @PathVariable Integer n2){
       try{
       Integer result=n1/n2;
       return "Result is "+result;
       }catch(ArithmeticException e){
       return "exception is "+e.getMessage();
       }
     } 
    

    一个Controller类中通常会有多个方法,这样多个方法中都写try语句进行异常处理会带来大量重复代码的编写,不易维护。

    Controller内部定义异常处理方法

    在Controller类中添加异常处理方法,代码如下:

    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String doHandleArithmeticException(ArithmeticException e){
     e.printStackTrace();
     return "计算过程中出现了异常,异常信息为"+e.getMessage();
    }
    

    @ExceptionHandler注解描述的方法为异常处理方法(注解中的异常类型为可处理的异常类型),假如Controller类中的逻辑方法中出现异常后没有处理异常,则会查找Controller类中有没有定义异常处理方法,假如定义了,且可以处理抛出的异常类型,则由异常处理方法处理异常。

    控制层中的全局异常处理类及方法定义

    当项目由多个控制层类中有多个共性异常的处理方法定义时,我们可以将这些方法提取到公共的父类对象中,但是这种方式是一种强耦合的实现,不利于代码的维护。我们还可以借助spring框架中web模块定义的全局异常处理规范进行实现,例如定义全局异常处理类,代码如下:

    package com.cy.pj.common.web;
    
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
     @ExceptionHandler(ArithmeticException.class)
     public String doHandleArithmeticException(ArithmeticException e){
      e.printStackTrace();
      return "计算过程中出现了异常,异常信息为"+e.getMessage();
     }
    } 
    

    其中,@RestControllerAdvice 注解描述的类为全局异常处理类,当控制层方法中的异常没有自己捕获,也没有定义其内部的异常处理方法,底层默认会查找全局异常处理类,调用对应的异常处理方法进行异常处理。


    最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请加Q君样:11604713672

    相关文章

      网友评论

          本文标题:springboot异常处理的基本规范

          本文链接:https://www.haomeiwen.com/subject/bsrdaktx.html