SpringMVC——表现层数据封装、异常处理器

embedded/2025/3/19 3:56:28/

目录

数据封装协议

为什么要进行数据封装

 实现数据封装

测试

异常处理器

实现异常处理器 

项目异常处理

实现处理不同的异常


数据封装协议

为什么要进行数据封装

当接口响应格式不一致时:

  1. 前端需要为不同接口编写多种解析逻辑

  2. 错误处理逻辑难以统一

  3. 接口文档维护成本增加

  4. 客户端难以快速判断请求结果


 那如何进行数据封装?

   前端接收数据格式——创建模型类,封装数据到data属性中、封装特殊消息到message中、封装操作结果到code中。

code:标识状态码

  •     告知客户请求处理的结果(成功/失败/异常)
  •     通过编码快速定位问题类型(参数错误、权限不足、系统异常)
  •     程序化处理:便于客户端编写统一的状态处理逻辑(根据code跳转页面或弹窗)

设计规范

状态码范围典型示例适用场景
2XX200业务成功
4XX400客户端错误
5XX500服务端错误
自定义业务码10011具体的业务错误

 msg:状态描述信息   

  •     可读提示:给开发者或用户展示友好提示信息

  •     问题定位辅助:配合 code 提供具体错误描述

  •     动态信息传递:支持参数化消息(如"用户 {userId} 不存在"

data:业务数据载体

  •     响应主体:承载接口实际返回的业务数据

  •     结构统一:保证不同接口的数据结构一致性

  •     空值处理:无数据时返回 null 或空对象({}/[]

 根据上面的原则就可以设置同一数据返回结果类:

public class Result {private Object data;private Integer code;private String msg;
}

    可以根据需要自行增减,提供方法方便操作。

 实现数据封装

    在controller包下面新建Result类,添加属性code、msg、data,加上对应的set和get方法,以及根据需求写出对应的构造方法:

public class Result {private Object data;private Integer code;private String msg;public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Result(Integer code, Object data, String msg) {this.data = data;this.code = code;this.msg = msg;}
    public Result( Integer code,Object data) {    //先码值再数据this.data = data;this.code = code;}public Result() {}
}

接下类设置状态码类:

同样是在contorller包下,新建code包:

public class Code {//1表示成功、0表示失败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;}

 这两项完成后,开始改变之前写的控制类:

@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@PostMappingpublic Result save(@RequestBody User user) {boolean flag = userService.save(user);return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag);}@PutMappingpublic Result update(@RequestBody User user) {boolean flag = userService.update(user);return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);}@DeleteMapping("/{id}")public Result delete(@PathVariable Integer id) {boolean flag = userService.delete(id);return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);}@GetMapping("/{id}")public Result getById(@PathVariable Integer id) {User user = userService.getById(id);Integer code = user != null ? Code.GET_OK : Code.GET_ERR;String msg = user != null ? "" : "数据查询失败";return new Result(code,user,msg);}@GetMappingpublic Result getAll() {List<User> users = userService.getAll();Integer code = users != null ? Code.GET_OK : Code.GET_ERR;String msg = users != null ? "" : "数据查询失败";return new Result(code,users,msg);}
}

和以前的代码对比:

测试

新增测试:

查询单个 

 

异常处理器

     在程序开发中,难免会出现异常情况:

    

    通常要根据异常现象的常见位置与诱因来处理。

常见的异常位置有:

  • 框架内部抛出的异常:因使用不合规导致
  • 数据层抛出的异常:因外部服务器故障导致(服务器访问超时)
  • 业务层抛出的异常:因业务逻辑书写错误导致(索引异常)
  • 表现层抛出的异常:因数据收集、校验等规则导致(不匹配的数据类型间接导致异常)
  • 工具类抛出的异常:因工具类书写不严谨不够健壮导致(必要释放的连接长期未释放)

SpringMVC提供了快速处理这些异常的方法,就是异常处理器。

实现异常处理器 

异常处理器就是集中,统一的处理项目中的异常。

    @RestControllerAdvice是Spring框架中的一个注解,该类中可以定义多个方法来处理不同类型的异常。这些方法使用@ExceptionHandler注解来指定要处理的异常类型。当控制器中抛出异常时,Spring会根据异常的类型调用相应的异常处理方法,将异常信息以RESTful的方式返回给客户端。

    异常处理器写在控制层,当出现异常时就会被拦截:

@RestControllerAdvice  //声明这个类用于异常处理
public class ProjectExceptionAdvice {@ExceptionHandler(Exception.class)  //拦截Exception异常public Result deException(Exception exception){System.out.println("拦截异常...");return new Result(666,null);}
}

    先写一个错误在查询所有的请求中,然后运行,发送请求:

 

项目异常处理

项目异常分类

业务异常

  • 规范用户行为产生的异常
  • 不规范用户行为操作产生的异常

系统异常

  • 项目运行过程中可预计且无法避免的异常

其他异常

  • 编程人员为预期到的异常

项目异常处理方案

业务异常

  • 发送对应消息传递给用户,提醒规范操作

系统异常

  • 发送固定信息传递给用户,安抚用户
  • 发送特定信息给运维人员,提醒维护 
  • 记录日志

其他异常

  • 发送固定信息传递给用户,安抚用户
  • 发送特定信息给编程人员,提醒维护
  •  记录日志

 

实现处理不同的异常

  • 创建exception包
  • 新建分别用于处理系统异常和业务异常类 
//继承RuntimeException,可以出现异常不处理向上抛
//系统异常
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;}}
//业务异常
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, Throwable cause ) {super(message, cause);this.code = code;}public BusinessException(Integer code,String message ) {super(message);this.code = code;}}

回到异常处理器,对不同的异常分别进行处理:

@RestControllerAdvice  //声明这个类用于异常处理
public class ProjectExceptionAdvice {@ExceptionHandler(Exception.class)  //拦截Exception异常public Result deException(Exception exception){//记录日志//发送消息到运维//发送消息给开发人员System.out.println("拦截异常...");return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙请稍后再试");}//拦截到系统异常@ExceptionHandler(SystemException.class)public Result deSystemException(SystemException exception){//记录日志//发送消息到运维//发送消息给开发人员return new Result(exception.getCode(),exception.getMessage());}//处理业务异常@ExceptionHandler(BusinessException.class)public Result deBusinessException(BusinessException exception){return new Result(exception.getCode(),exception.getMessage());}
}


http://www.ppmy.cn/embedded/173754.html

相关文章

游戏引擎学习第161天

回顾并计划今天的工作 我们从头开始编写一款完整的游戏&#xff0c;完全不依赖游戏引擎和库。我们会从最基本的渲染代码开始&#xff0c;一直到高层的AI代码&#xff0c;涵盖其中的一切。 目前&#xff0c;我们正在做一些比较轻松有趣的事情&#xff0c;可以说是比较随意的内…

deepseek连续对话与API调用机制

在调用DeepSeek等大模型进行连续对话时&#xff0c;是否需要每次上传系统提示和对话历史取决于API的设计机制。 一、API调用机制解析 无状态服务原则 DeepSeek的API基于无状态架构设计&#xff0c;每次请求视为独立会话。若需维持对话连续性&#xff0c;必须由客户端主动管理并…

2024浙江大学计算机考研上机真题

2024浙江大学计算机考研上机真题 2024浙江大学计算机考研复试上机真题 2024浙江大学计算机考研机试真题 2024浙江大学计算机考研复试机试真题 历年浙江大学计算机复试上机真题 历年浙江大学计算机复试机试真题 2024浙江大学计算机复试上机真题 2024浙江大学计算机复试机试真题 …

为什么需要使用十堰高防服务器?

十堰高防服务器的核心价值与应用必要性 一、‌应对复杂攻击的防御能力‌ ‌T级DDoS攻击防护‌ 十堰高防服务器搭载 ‌T级清洗中心‌&#xff0c;支持智能流量调度与分层处理&#xff0c;可抵御 ‌800Gbps-1.2Tbps‌ 的大规模混合攻击&#xff08;如SYN Flood、UDP反射&#xff…

基于Pygame实现2048小游戏

目录 1. 项目概述 2. 开发环境 3. 核心代码 3.1 网格初始化 3.2 数字生成逻辑 3.3 移动与合并算法 4. 图形界面设计 4.1 颜色方案 4.2 界面元素 4.3 动画效果 5. 代码结构说明 6. 完整代码 7. 总结与扩展 1. 项目概述 2048是一款风靡全球的数字益智游戏&#xff…

SpringData Redis缓存:自定义序列化与过期策略

文章目录 引言一、Spring Cache与Redis集成基础二、Redis缓存配置基础三、自定义序列化策略四、实现自定义序列化器五、多级缓存配置六、自定义过期策略七、缓存注解的高级应用八、实现缓存预热与更新策略九、缓存监控与统计总结 引言 在现代高并发分布式系统中&#xff0c;缓…

记录一次wifi版有人物联串口服务器桥接网络调试经过

目前的项目想法是将一台设备IP192.168.3.56的设备通过网口发给串口服务器&#xff0c;然后串口服务器通过桥接&#xff0c;将这个数据通过wifi路由器转发给另外一台设备IP为192.168.3.17&#xff0c;其中串口服务器的IP为192.168.3.16&#xff0c;wifi路由器组成的局域网的网管…

【操作系统安全】任务4:Windows 系统网络安全实践里常用 DOS 命令

目录 一、引言 二、网络信息收集类命令 2.1 ipconfig 命令 2.1.1 功能概述 2.1.2 实例与代码 2.2 ping 命令 2.2.1 功能概述 2.2.2 实例与代码 2.3 tracert 命令 2.3.1 功能概述 2.3.2 实例与代码 三、网络连接与端口管理类命令 3.1 netstat 命令 3.1.1 功能概述…