Spring Boot 中统一忽略审计字段的优雅实践

发布时间 - 2025-12-31 00:00:00    点击率:

本文介绍如何在 spring boot 项目中通过抽象基类 + `@jsonignore` 实现审计字段(如 createdby、createddate)的全局序列化屏蔽,避免在每个实体类中重复添加注解,提升代码复用性与可维护性。

在构建 RESTful API 时,JPA 审计功能(如 @CreatedBy、@CreatedDate)极大简化了元数据管理,但这些字段通常不应暴露在 API 响应中——既涉及数据安全(如用户 ID 泄露),也违背接口契约的简洁性原则。若为数十个实体逐一添加 @JsonIgnore 或 @JsonIgnoreProperties,不仅冗余,还易遗漏、难维护。

一个高效且符合 DRY 原则的解决方案是:定义统一的审计基类,集中声明并屏蔽审计字段

✅ 推荐实现:@MappedSuperclass + @JsonIgnore 全局控制

使用 @MappedSuperclass 定义抽象父类,将所有公共审计字段及其 Jackson 序列化控制逻辑内聚于此。所有业务实体继承该类后,自动获得审计能力与响应屏蔽能力:

@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class AuditableEntity : Serializable {
    companion object {
        private const val serialVersionUID = -5554308939380869754L
    }

    @Column(name = "created_at", updatable = false)
    @CreationTimestamp
    @JsonIgnore // ← 关键:统一屏蔽,不参与 JSON 序列化
    var createdAt: LocalDateTime? = null

    @Column(name = "created_by", updatable = false)
    @CreatedBy
    @JsonIgnore
    var createdBy: String? = null

    @Column(name = "updated_at")
    @UpdateTimestamp
    @JsonIgnore
    var updatedAt: LocalDateTime? = null

    @Column(name = "updated_by")
    @LastModifiedBy
    @JsonIgnore
    var updatedBy: String? = null

    // 可选:提供友好格式化的时间字符串(仅用于读取,不映射数据库)
    val createdAtStr: String
        get() = createdAt?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) ?: ""

    val updatedAtStr: String
        get() = updatedAt?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) ?: ""
}

随后,您的业务实体只需简单继承即可:

@Entity
@Table(name = "users")
class User : AuditableEntity() {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @Column(name = "username", nullable = false)
    var username: String? = null

    @Column(name = "email")
    var email: String? = null
}

效果验证:调用 GET /api/users/1 时,响应 JSON 中将完全不包含 createdAt、createdBy 等字段,无需任何额外配置。

⚠️ 注意事项与增强建议

  • 确保启用 JPA Auditing:在主配置类或启动类上添加 @EnableJpaAuditing,并配置 AuditorAware Bean;
  • 时间类型推荐 LocalDateTime:相比 Date,它更符合现代 Java 时间 API,且与数据库 TIMESTAMP 映射更自然(需确认 JDBC 驱动支持);
  • 如需部分场景暴露审计信息(如管理后台),可结合 @JsonView 或自定义序列化器实现条件化输出,而非全局屏蔽;
  • 避免在基类中使用 @JsonIgnoreProperties:它作用于整个类,粒度粗且无法与 @JsonIgnore 共存;@JsonIgnore 字段级控制更精准、可继承、易调试;
  • 数据库字段命名建议统一加前缀/后缀(如 _at, _by),便于 SQL 审计追踪,也利于团队规范。

通过这一设计,您不仅消除了重复注解,更将审计生命周期管理(存储)与表现层关注点(序列化)清晰分离,真正践行了关注点分离(SoC)与开闭原则(OCP)——新增实体只需继承,无需修改序列化逻辑。


# java  # js  # json  # app  # ai  # 一加  # restful api  # 代码复用  # yy 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何快速搭建自助建站会员专属系统?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  音乐网站服务器如何优化API响应速度?  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  如何获取PHP WAP自助建站系统源码?  如何为不同团队 ID 动态生成多个“认领值班”按钮  零基础网站服务器架设实战:轻量应用与域名解析配置指南  浅析上传头像示例及其注意事项  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  ,交易猫的商品怎么发布到网站上去?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  Java类加载基本过程详细介绍  如何在阿里云部署织梦网站?  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  如何制作一个表白网站视频,关于勇敢表白的小标题?  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  Laravel如何发送系统通知?(Notification渠道示例)  Laravel如何使用.env文件管理环境变量?(最佳实践)  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  油猴 教程,油猴搜脚本为什么会网页无法显示?  Laravel的.env文件有什么用_Laravel环境变量配置与管理详解  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  详解jQuery中基本的动画方法  如何获取免费开源的自助建站系统源码?  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  高端建站三要素:定制模板、企业官网与响应式设计优化  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  大型企业网站制作流程,做网站需要注册公司吗?  Laravel如何生成API文档?(Swagger/OpenAPI教程)  简历在线制作网站免费版,如何创建个人简历?  个人摄影网站制作流程,摄影爱好者都去什么网站?  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  网站建设整体流程解析,建站其实很容易!  MySQL查询结果复制到新表的方法(更新、插入)  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  Swift中循环语句中的转移语句 break 和 continue  JavaScript Ajax实现异步通信  Laravel如何实现数据库事务?(DB Facade示例)  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  公司门户网站制作流程,华为官网怎么做?  C#如何调用原生C++ COM对象详解  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】