企业级 SpringBoot 后端通用开发规范|统一响应 + 敏感字段加密

本文为后端团队通用开发规范,聚焦接口统一响应封装数据库敏感字段自动加解密两大核心场景,配套可直接落地的代码示例,解决前后端交互混乱、数据安全合规、代码维护成本高的问题,适用于抽奖系统、用户中心等各类 SpringBoot 后端项目。


一、规范总纲

1. 核心目标

  • 统一接口返回格式,降低前后端联调成本
  • 敏感数据加密存储,满足数据安全合规要求
  • 业务代码与通用逻辑解耦,提升可维护性
  • 全局标准化,减少重复造轮子与低级 Bug

2. 适用范围

SpringBoot + MyBatis/MyBatis-Plus 项目,Controller/DAO 层通用规范。


二、接口统一响应规范(CommonResult<T>)

1. 为什么需要统一响应?

  • 原生接口返回结构杂乱,成功返数据、失败抛异常,前端需多套解析逻辑
  • 错误码、提示信息无统一标准,排查问题困难
  • 业务代码与响应格式耦合,扩展性差

2. 统一响应结构

固定返回code+msg+data,前端一套逻辑适配所有接口:

复制代码
{
  "code": 200,
  "msg": "操作成功",
  "data": {}
}

3. 完整代码实现

j

复制代码
import java.io.Serializable;

/**
 * 全局统一响应封装
 */
public class CommonResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    // 成功状态码
    public static final int SUCCESS = 200;
    // 服务器异常
    public static final int ERROR = 500;
    // 参数错误
    public static final int BAD_REQUEST = 400;
    // 未授权
    public static final int UNAUTHORIZED = 401;

    private Integer code;
    private String msg;
    private T data;

    // 全参构造
    public CommonResult(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    // 成功响应(带数据)
    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<>(SUCCESS, "操作成功", data);
    }

    // 成功响应(无数据)
    public static <T> CommonResult<T> success() {
        return new CommonResult<>(SUCCESS, "操作成功", null);
    }

    // 失败响应
    public static <T> CommonResult<T> error(int code, String msg) {
        return new CommonResult<>(code, msg, null);
    }

    // Getter & Setter
    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 T getData() {return data;}
    public void setData(T data) {this.data = data;}
}

4. 接口使用示例

复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/{id}")
    public CommonResult<UserDTO> getUserById(@PathVariable Long id) {
        UserDTO user = userService.getUserById(id);
        return CommonResult.success(user);
    }

    @PostMapping("/add")
    public CommonResult<Void> addUser(@RequestBody UserDTO userDTO) {
        userService.addUser(userDTO);
        return CommonResult.success();
    }
}

5. 规范优势

  • 泛型<T>支持任意数据类型,复用性拉满
  • 静态方法快速构建响应,一行代码完成返回
  • 状态码统一管理,避免魔法值
  • 实现序列化,支持 JSON 网络传输

三、数据库敏感字段自动加解密规范

1. 应用场景

手机号、身份证、银行卡等敏感信息,明文存储违反合规要求,需加密入库、解密出库。

2. 实现方案

基于 MyBatis 自定义TypeHandler,实现写入自动加密、查询自动解密,业务代码无侵入。

3. 步骤 1:定义加密标记类

用于标识需要加解密的字段:

复制代码
package com.example.lotterysystem.dao.dataobject;

/**
 * 敏感字段加密标记类
 */
public class Encrypt {
    private String value;

    public Encrypt(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

4. 步骤 2:自定义加解密类型处理器

复制代码
package com.example.lotterysystem.dao.handler;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.example.lotterysystem.dao.dataobject.Encrypt;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 敏感字段AES自动加解密处理器
 */
@MappedTypes(Encrypt.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptTypeHandler extends BaseTypeHandler<Encrypt> {

    // AES密钥(16字节,生产环境需配置化,禁止硬编码)
    private static final byte[] KEY = "123456789abcdefg".getBytes(StandardCharsets.UTF_8);

    /**
     * 写入数据库:明文加密为密文
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null || !StringUtils.hasText(parameter.getValue())) {
            ps.setString(i, null);
            return;
        }
        AES aes = SecureUtil.aes(KEY);
        String encryptStr = aes.encryptHex(parameter.getValue());
        ps.setString(i, encryptStr);
    }

    /**
     * 读取数据库:密文解密为明文
     */
    @Override
    public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return decrypt(rs.getString(columnName));
    }

    @Override
    public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return decrypt(rs.getString(columnIndex));
    }

    @Override
    public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return decrypt(cs.getString(columnIndex));
    }

    /**
     * 解密方法
     */
    private Encrypt decrypt(String str) {
        if (!StringUtils.hasText(str)) {
            return null;
        }
        String decryptStr = SecureUtil.aes(KEY).decryptStr(str);
        return new Encrypt(decryptStr);
    }
}

5. 步骤 3:实体类使用示例

复制代码
package com.example.lotterysystem.dao.dataobject;

/**
 * 用户DO
 */
public class UserDO {
    private Long id;
    private String userName;
    // 敏感字段:手机号,自动加解密
    private Encrypt phone;
    private Integer age;

    // Getter & Setter
}

6. 执行流程

  • 写入:Encrypt(明文) → TypeHandler 加密 → 数据库存储密文
  • 读取:数据库密文 → TypeHandler 解密 → Encrypt(明文)

7. 生产环境优化建议

  • 密钥从配置中心 / 环境变量读取,禁止硬编码
  • 加解密添加try-catch,避免解密失败导致服务崩溃
  • 密钥定期轮换,提升安全性

四、配套规范补充

1. 异常处理规范

结合统一响应,全局捕获异常并封装返回:

复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public CommonResult<Void> handleException(Exception e) {
        return CommonResult.error(CommonResult.ERROR, "服务器异常:" + e.getMessage());
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public CommonResult<Void> handleBadRequest(IllegalArgumentException e) {
        return CommonResult.error(CommonResult.BAD_REQUEST, e.getMessage());
    }
}

2. 分层开发规范

  • Controller:仅处理请求参数、返回统一响应
  • Service:专注业务逻辑,不关心响应格式
  • DAO:数据交互,敏感字段自动加解密
  • 禁止跨层调用,保持职责单一

五、规范价值总结

  1. 前端体验提升:统一响应格式,一套解析逻辑,联调效率提升 50%+
  2. 后端开发高效:通用封装减少重复代码,专注业务实现
  3. 数据安全合规:敏感字段自动加密,满足监管要求
  4. 项目可维护性:全局标准化,新人快速上手,迭代成本更低

六、落地注意事项

  1. 统一响应类全局唯一,禁止自定义多个响应类
  2. 敏感字段仅标记核心隐私数据,避免过度加密影响性能
  3. 生产环境务必替换硬编码密钥,优先使用配置中心管理
  4. 加解密逻辑添加日志,便于问题排查
相关推荐
前端白袍17 小时前
代码规范:RESTful API 全面介绍
后端·restful·代码规范
神奇小汤圆17 小时前
一次 JVM OOM,资深工程师应该如何完整复盘?
后端
孟陬17 小时前
一个小小 alias,提升开发幸福感
前端·后端·命令行
JunLa18 小时前
OpenClaw Agent
后端
happymaker062618 小时前
Spring学习日记——DAY03(yml文件)
java·spring boot·spring
AskHarries18 小时前
为什么大多数人创业第一步就错了
人工智能·后端
tyung18 小时前
Go 手写二叉堆优先队列:避开 container/heap 的性能陷阱
数据结构·后端·go
Nirvana在掘金18 小时前
MySQL 事务隔离级别 锁 高并发场景优化经验
后端·mysql
李小狼lee18 小时前
《spring如此简单》第二节--IOC思想的实现,容器是什么
后端·面试
GetcharZp18 小时前
深入浅出 etcd:从 K8s 灵魂到 Golang 实战,分布式系统的“定海神针”!
后端