Java实体对象常见分类

1.实体对象常见分类

在 Java Web 项目里,常见的实体类可以分成 3 类:

  1. 持久化实体(Entity / Domain / Model)

  1. 直接映射数据库表,一般在 entity/pojo/model/domain 包里。
  2. 字段多,几乎和数据库列一一对应:id, role, balance, status, password 等。
  3. 典型注解:@Entity、@Table、@Id(JPA),或者只是 MyBatis 的 POJO。
  1. 数据传输对象(DTO,Data Transfer Object)

  1. 用来做“数据搬运”,封装接口输入输出。
  2. 字段只包含 业务需要的内容,不会完整等同数据库字段。
  3. 常在 dto、vo、form 包里。
    比如 UserUpdateForm、LoginRequestDto。
  1. 表单对象 / 视图对象(Form / VO, View Object)

  1. 更贴近页面/接口的输入输出。
  2. 和 DTO 很像,有的项目里 DTO 和 Form/VO 不严格区分。

2. 如何区分绑定的是 Entity 还是 DTO?

审计时可以从这几个角度判断:

包路径:

com.xxx.entity、com.xxx.model → 多半是持久化实体。
com.xxx.dto、com.xxx.form、com.xxx.vo → 基本就是 DTO/表单对象。

字段内容:

如果类里有 id、role、isAdmin、balance、status、createTime → 高度怀疑是数据库实体。
如果类只包含业务输入字段(比如 email, nickname)→ 这是 DTO。

是否有 ORM 注解:

@Entity, @Table, @Column, @Id → 这是持久化实体。
DTO 一般没有数据库映射注解。

命名习惯:

User → 常见的是数据库实体。
UserUpdateForm, UserDto, LoginRequest → 一看就是 DTO/表单对象。

3. 你给的两个代码示例对比

❌ 例1:绑定 Entity

@PostMapping("/update")
public String updateUser(@ModelAttribute User user) {
    userService.update(user);
    return "ok";
}

这里的 User 大概率是 数据库实体(包含敏感字段)。
Spring MVC 会自动把 HTTP 参数填充进 User 对象。
如果攻击者多传一个 role=admin,就能直接覆盖数据库里的角色字段。
风险点:关键参数篡改漏洞。
✅ 例2:绑定 DTO

@PostMapping("/update")
public String updateUser(@ModelAttribute UserUpdateForm form, Principal principal) {
    User user = userService.findByUsername(principal.getName());
    user.setEmail(form.getEmail());
    user.setNickname(form.getNickname());
    userService.update(user);
    return "ok";
}

这里的 UserUpdateForm 是 DTO(只包含 email、nickname)。
用户传 role=admin,Spring MVC 也找不到对应字段,不会赋值。
最终 userService.update(user) 时,只有允许修改的字段被更新。
安全性:避免了关键参数篡改。

4.总结

Entity(持久化实体):字段多,映射数据库,绝不能直接用来绑定前端输入。

DTO/Form(数据传输对象/表单对象):只暴露安全字段,推荐绑定。

👉 在你看代码时,如果看到 Controller 方法直接用 Entity 做参数,审计结论就是:
“存在关键参数篡改风险,应改用 DTO/Form 对象或增加字段白名单限制”。

Entity vs DTO/Form 对比表

对比维度Entity(持久化实体)DTO/Form(数据传输/表单对象)
字段组成基本等同数据库表的全部字段:id, role, isAdmin, balance, createTime, status只包含业务输入/输出需要的字段,例如 email, nickname, passwordConfirm
用途映射数据库表,用于 ORM(JPA、Hibernate、MyBatis),直接存取数据库用于接口请求/响应的数据交换,不直接映射数据库
常见位置包路径:entity/pojo/model/domain,常带 ORM 注解(@Entity, @Table包路径:dto/form/vo/request/response,一般没有 ORM 注解
典型特征字段多且全面,包含敏感字段(如权限、余额、主键 id)精简、面向业务场景,只暴露安全字段
示例类名User, Order, AccountUserUpdateForm, LoginRequestDto, OrderResponseVo
安全风险❌ 如果直接绑定到 HTTP 请求,攻击者可篡改敏感字段(如 role=adminbalance=99999) → 关键参数篡改漏洞✅ 只包含允许修改/返回的字段,不会暴露敏感字段,避免篡改风险
审计提示🔍 重点关注 Controller 方法参数是否直接使用 Entity,例如:
public String update(@ModelAttribute User user)
⚠️ 风险点:敏感字段可能被篡改
审计结论:绑定 DTO/Form 通常是安全做法,但要确认 DTO 中是否仍然意外包含敏感字段
最佳实践- 不直接暴露给前端请求绑定
- Entity ↔ DTO 转换在 Service 层或使用 MapStruct 等工具
- 每个接口专门定义输入/输出 DTO
- DTO 字段经过严格白名单控制

“Entity 全表字段,DTO 精选字段。Entity 不能绑输入,DTO 专绑输入。”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值