You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.5 KiB

Controller 出入参两类对象规范(Param / DTO)

Status: ready-for-agent ADR: ADR-0017

入参查询用 XxxParam,入参写入和出参都用 XxxDTO,Entity 永不出现在 Controller 方法签名上。

一句话规则

  • 写新接口:查询/分页 → 建 XxxParam extends BaseParam;写入/保存 → 参数 ≥3 建一个 XxxDTO,≤2 保持 @RequestParam
  • 写新出参:建 XxxDTO,业务类继承 BaseDTO 白拿 id / createTime / updateTime
  • 想直接返回实体:不行

对象职责

类型 用途 继承 硬约束
XxxParam param/ 查询/搜索/分页入参 extends BaseParam 必须经 PageConverter.toMpPage 转换
XxxDTO dto/ 写入参 + 出参(双向) 业务类 extends BaseDTO;统计/登录等无主键语义的不继承 fromEntity() / toEntity() 写在 DTO 上,Service 层调用
Entity domain/entity/ 表结构映射 extends BaseEntity 禁止出现在任何 Controller 方法签名中

硬约束

  1. Entity 不出现在 Controller 方法签名上(入参出参都禁)
  2. deleted 不出现在任何 HTTP 响应中
  3. creatorId / updaterId 不出现在任何 HTTP 响应中

Mass assignment 防御

全局 @ControllerAdvice + @InitBinderdataBinder.setDisallowedFields(...) strip 掉服务端裁定字段:

createTimeupdateTimecreatorIdupdaterIddeletedbuiltin

新增服务端裁定字段时必须同步更新此列表。

封装阈值

≥3 个参数封装为 XxxDTO;≤2 个保持 @RequestParam。纯参数个数,不看点参数形状。

命名规则

dto/ 包内所有 HTTP 出入参类一律 XxxDTO 后缀。内部传输对象(ButtonSeedPermissionModuleDescriptorUploadSession)不强制后缀。

绑定方式

隐式表单绑定(不加 @RequestBody),契合项目 application/x-www-form-urlencoded 契约。

存量改名清单

原名 新名 模块
RoleDetailVO RoleDTO crm-auth
UserStatsVO UserStatsDTO crm-auth
DictGroupVO DictGroupDTO crm-dict
DictItemVO DictItemDTO crm-dict
ResourceNode ResourceNodeDTO crm-auth

存量违规回填清单(9 处)

# 违规 位置 改法
1 实体直收 DictGroupController.saveOrUpdate(DictGroup) 改为 saveOrUpdate(DictGroupDTO)
2 实体直收 DictItemController.saveOrUpdate(DictItem) 改为 saveOrUpdate(DictItemDTO)
3 实体直出 RoleController.pageResult<PageResult<SysRole>> 改为 Result<PageResult<RoleDTO>>
4 实体直出 SystemController.menuTreeList<SysMenu> 改为 List<ResourceNodeDTO>
5 实体直出 SystemController.deptTreeList<SysDept> 改为 List<DeptDTO>
6 实体直出 DictGroupController.enabledListList<DictGroup> 改为 List<DictGroupDTO>
7 实体直出 DictItemController.enabledListList<DictItem> 改为 List<DictItemDTO>
8 分页绕过 RoleController.page 自行 new Page<> 改为 RoleParam extends BaseParam,经 PageConverter
9 @RequestBody SystemController.userPage 去掉 @RequestBody,改表单绑定

前置条件

BaseDTO 必须先重构(当前仍是未改造版本):

  • 改为 abstract
  • 只保留 idcreateTimeupdateTime
  • 三字段加 @JsonInclude(NON_NULL)
  • 移除 creatorIdupdaterIddeleted 及默认值
  • 移除泛型 toEntity(Supplier) 方法

术语表

术语 定义
Param (XxxParam) 查询/搜索/分页入参对象,放 param/ 包,继承 BaseParam,经 PageConverter 转换
DTO (XxxDTO) 双向传输对象,既是写入参又是出参,放 dto/ 包;业务类继承 BaseDTO
BaseParam 分页参数基类,提供 current / size / asc / desc + PageConverter 转换
BaseDTO 出参基类(abstract),提供 id / createTime / updateTime + @JsonInclude(NON_NULL)
InitBinder 防护 全局 @InitBinder + setDisallowedFields,strip 服务端裁定字段防 mass assignment
PageConverter 分页转换器,页大小上限收敛 + 排序字段白名单校验
封装阈值 ≥3 个参数封 XxxDTO,≤2 保持 @RequestParam
Route A 同一个 DTO 类同时做写入参和出参(用户已接受双契约字段代价)