【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理

这篇学习笔记是Spring系列笔记的第7篇,该笔记是笔者在学习黑马程序员SSM框架教程课程期间的笔记,供自己和他人参考。


Spring学习笔记目录

笔记1:【SSM】Spring基础: IoC配置学习笔记-CSDN博客 对应黑马课程P1~P20的内容。

笔记2: 【SSM】Spring学习笔记2:注解配置bean_ssm黑马笔记-CSDN博客 对应黑马课程P21~P27

笔记3: 【SSM】Spring学习笔记3:Spring整合MyBatis和Junit_spring整合mybaits-CSDN博客 对应黑马课程P28~30

笔记4:【SSM】Spring学习笔记4:Spring的AOP编程-CSDN博客 对应黑马课程P31~39

笔记5:【SSM】Spring学习笔记5:Spring事务-CSDN博客 对应黑马课程P40~42

笔记6: 【SSM】SpringMVC学习笔记6:SpringMVC入门-CSDN博客 对应黑马课程P43~58

笔记7: 此篇 对应黑马课程P59~65

笔记8:【SSM】SpringMVC学习笔记8:拦截器-CSDN博客 对应黑马课程P71~74

笔记9:【SSM】SpringBoot学习笔记1:SpringBoot快速入门-CSDN博客 对应黑马课程P90~101


1.表现层与前端的数据传输协议

一般将需要传递的数据,封装成一个统一的格式。

如下的一种协议规定:data封装要传输的数据,code标记传递的数据类型/以及操作是否成功的状态,msg传输操作失败时候传输的信息。

该协议不固定,主要由前后端人员协调好。

java 复制代码
public class Result {
    private Object data;
    private Integer code;
    private String msg;

    public Result() {
    }

    public Result(Integer code,Object data) {
        this.data = data;
        this.code = code;
    }

    public Result(Integer code, Object data, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

    //所有属性得到getter/setter方法和toString()
}

状态码code用一个枚举类来维护。

java 复制代码
public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;

    public static final Integer BUSINESS_ERR = 60002;
}

在controller类里面返回的数据类型统一成result

java 复制代码
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookService bookService;

    @PostMapping
    public Result save(@RequestBody Book book) {
        boolean flag = bookService.save(book);
        return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
    }

    @PutMapping
    public Result update(@RequestBody Book book) {
        boolean flag = bookService.update(book);
        return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        boolean flag = bookService.delete(id);
        return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
    }

    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {
        Book book = bookService.getById(id);
        Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
        String msg = book != null ? "" : "数据查询失败,请重试!";
        return new Result(code,book,msg);
    }

    @GetMapping
    public Result getAll() {
        List<Book> bookList = bookService.getAll();
        Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
        String msg = bookList != null ? "" : "数据查询失败,请重试!";
        return new Result(code,bookList,msg);
    }
}

2. 异常处理

2.1 常见异常的诱因

2.2 异常处理类

为了统一管理,异常可以层层上抛,抛到表现层(写controller那一层)处理。

@RestControllerAdvice

声明这个类是个异常处理类,注解@RestControllerAdvice用于全局性处理Controller抛出的异常。

@ExceptionHandler

用于方法上面,标注该方法用于处理什么类型的异常,注解参数接受异常类型。

异常处理之后要返回result信息,因为该异常是表现层处理的异常,而表现层直接和前端相连。返回的result最终会被前端接收。

java 复制代码
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
//豆包:主要用于全局性地处理控制器(Controller)所抛出的异常,并且会直接返回 JSON、XML 这类格式的数据,而非视图。
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //具体的异常处理......
        return new Result(ex.getCode(),null,ex.getMessage());
    }
}

2.3 项目异常处理*

2.3.1 异常分类

项目中的异常可以分为下三种异常,实际情况根据具体情况来定

2.3.2 自定义异常

针对自己对项目划分的异常种类,自定义异常

自定义的异常需要继承自已有的异常类型。需要为自定义异常提供构造器(根据需要)。自定义异常中自定义属性code,需要提供get方法和set方法。

业务异常

java 复制代码
//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

系统异常

java 复制代码
public class SystemException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public SystemException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

}

2.3.4 处理自定义异常

在异常处理类中对三种异常分别处理。其中resule返回的信息从异常对象中获取。

java 复制代码
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

2.3.5 使用自定义异常

系统遇到一个异常会不会自动识别成自定义异常,需要在异常可能出现的地方手动包装成自定义异常。

java 复制代码
public Book getById(Integer id) {
    //模拟业务异常,包装成自定义异常
    if(id == 1){
        throw new BusinessException(Code.BUSINESS_ERR,"业务异常");
    }
    //模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
    try{
        int i = 1/0;
    }catch (Exception e){
        throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
    }
    return bookDao.getById(id);
}
相关推荐
天水幼麟3 小时前
动手学深度学习-学习笔记(总)
笔记·深度学习·学习
天水幼麟5 小时前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
绿皮的猪猪侠5 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
沧海一笑-dj5 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
老虎06276 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
大苏打seven7 小时前
Docker学习笔记:Docker网络
笔记·学习·docker
Green1Leaves8 小时前
pytorch学习-9.多分类问题
人工智能·pytorch·学习
慕y2749 小时前
Java学习第十五部分——MyBatis
java·学习·mybatis
碣石潇湘无限路9 小时前
【AI篇】当Transformer模型开始学习《孙子兵法》
人工智能·学习
kikikidult11 小时前
(2025.07)解决——ubuntu20.04系统开机黑屏,左上角光标闪烁
笔记·ubuntu