自定义注解
实体引用
@IncludeReferenceEntities
说明
作用目标为方法或类型。标明查询被标注的控制器方法的返回结果的关联实体。
示例
@CrossOrigin
@RestController
@Tag(name = "系统:基础服务")
@Tag(name = "领域:组织管理")
@Tag(name = "职责:查询操作")
@Tag(name = "实体:职员")
public class EmployeeQueryController
extends AbstractDomainEntityQueryController<EmployeeQueryEntity> implements EmployeeQueryApi {
@Override
@IncludeReferenceEntities
@PreAuthorize("principal.username == #userId OR hasRole('ADMINISTRATOR')")
@Operation(summary = "取得用户加入的租户")
public Page<EmployeeQueryEntity> tenants(@Parameter(description = "用户 ID") String userId,
@Valid EmployeeTenantQueryDTO queryDTO) {
return employeeQueryService.employees(userId, queryDTO);
}
...
}
@ReferenceEntity
说明
作用目标为属性。标明该属性关联实体信息。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
value | 引用实体的类型 |
示例
@Data
@MappedSuperclass
@Schema(title = "职员实体")
@EqualsAndHashCode(callSuper = true)
public abstract class EmployeeEntity extends AbstractVersionedEntity implements TenantVersionedEntity, ToggleableEntity {
@JsonProperty("tenant")
@ReferenceEntity(OrganizationEntity.class)
@Schema(title = "租户")
private String tenantId;
...
}
验证约束
@EmailAddress
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素必须为电子邮箱地址格式。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.EmailAddressNotValid} |
示例
@Getter
@Setter
@Schema(title = "登录密码重置表单数据传输对象")
public class UserPasswordResetDTO extends AbstractDTO {
@EmailAddress
@Schema(title = "电子邮箱地址", hidden = true)
private String email;
...
}
@GeoLocation
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素必须为一个有效的地理位置坐标。
- 必须为浮点数数组
- 必须包含两个元素
- 第一个元素为经度,取值范围为 -180~180
- 第二个元素为纬度,取值范围为 -90~90
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.GeoLocationNotValid} |
示例
@Getter
@Setter
@Schema(title = "配送据点命令操作表单数据传输对象")
public abstract class ShipmentLocationCommandDTO extends AbstractDTO {
@GeoLocation
@Schema(title = "地理位置坐标([经度, 纬度])")
private Double[] location;
...
}
@IncompatibleProperties
说明
作用目标类型使用时,标明指定的属性互斥。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
value | 互斥的属性的名称的数组 | |
message | 错误消息 | {error.validation.conflict} |
示例
@Getter
@Setter
@Schema(title = "职员邀请表单数据传输对象")
@RequireAtLeastOneProperty({"userId", "userCredential"})
@IncompatibleProperties({"userId", "userCredential"})
public class EmployeeInviteDTO extends EmployeeCommandDTO {
@ObjectID
@Schema(title = "用户 ID(已注册用户)")
private String userId;
@UsernameOrEmailOrMobile
@Schema(title = "用户登录用户名、电子邮箱地址或手机号码(新用户)")
private String userCredential;
...
}
@MobileNumber
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素必须为手机号码格式。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.MobileNumberNotValid} |
示例
@Getter
@Setter
@Schema(title = "手机号码凭证命令数据传输对象")
public class MobileCredentialCommandDTO extends AbstractDTO {
@NotBlank
@MobileNumber
@Schema(title = "手机号码")
private String mobile;
...
}
@NotBlankNullable
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素可以为 null,但不可为空字符串,且必须包含至少一个非空白字符。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {javax.validation.constraints.NotBlank.message} |
示例
@Getter
@Setter
@Schema(title = "角色组更新表单数据传输对象")
public class RoleUpdateDTO extends RoleCommandDTO {
@NotBlankNullable
@Schema(title = "名称")
private String name;
}
@NotEmptyNullable
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素可以为 null,但不可为空字符串,或空列表。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {javax.validation.constraints.NotEmpty.message} |
示例
@Getter
@Setter
@Schema(title = "电子邮件配置更新表单数据传输对象")
public class MailConfigurationUpdateDTO extends AbstractDTO {
@NotEmptyNullable
@Size(max = 255)
@Schema(title = "密码")
private String password;
...
}
@ObjectID
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。 被标注的元素必须为有效的 Object ID,即 24 位十六进制字符串。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.ObjectIdNotValid} |
示例
@Getter
@Setter
@Schema(title = "职员创建表单数据传输对象")
@EqualsAndHashCode(callSuper = true)
public class TenantEmployeeCreateDTO extends EmployeeCreateDTO {
@NotBlank
@ObjectID
@Schema(title = "租户 ID")
private String tenantId;
}
@RequireAtLeastOneProperty
说明
作用目标为类型使用时。 标明指定的属性中必须设定至少一项。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
value | 必要属性的名称的数组 | |
message | 错误消息 | {error.validation.required} |
示例
@Getter
@Setter
@Schema(title = "职员创建表单数据传输对象")
@EqualsAndHashCode(callSuper = true)
public class TenantEmployeeCreateDTO extends EmployeeCreateDTO {
@NotBlank
@ObjectID
@Schema(title = "租户 ID")
private String tenantId;
}
@RequiredProperties
说明
作用目标为类型声明时。 检查必要属性是否均被设置。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
value | 必要属性的名称的数组 | |
message | 错误消息 | {javax.validation.constraints.NotNull.message} |
示例
@Getter
@Setter
@Schema(title = "短信发送配置更新表单数据传输对象")
@RequiredProperties({"name", "provider", "username", "password", "signName"})
public class SmsConfigurationCreateDTO extends SmsConfigurationUpdateDTO {
}
@Username
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素必须为自定义登录用户名格式。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.UsernameNotValid} |
示例
@Getter
@Setter
@Schema(title = "用户创建表单数据传输对象")
public class UserCreateDTO extends UserCommandDTO {
@Username
@Schema(title = "登录用户名")
private String username;
...
}
@UsernameOrEmailOrMobile
说明
作用目标为:方法、属性、注解类型、构造方法、方法参数、类型使用等。被标注的元素必须为自定义登录用户名、电子邮箱地址或手机号码格式。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
message | 错误消息 | {error.validation.UsernameNotValid} |
示例
@Getter
@Setter
@Schema(title = "登录认证表单数据传输对象")
public class AuthenticationDTO extends AbstractDTO {
@NotBlank
@UsernameOrEmailOrMobile
@Schema(title = "登录用户名、电子邮箱地址或手机号码等")
private String username;
...
}
访问控制
@EnableAccessLog
说明
标注在 Controller 中的非服务间内部调用的方法上,用于生成 REST API 访问日志。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
enable | 是否开启用户访问日志 | true |
tenantId | 租户ID路径参数名称 | tenantId |
示例
@Override
@EnableAccessLog
@Operation(summary = "创建用户帐号(用户注册)")
public UserCommandEntity createUser(@Valid UserCreateDTO createDTO) {
...
}
@ServerInternalAccessOnly
说明
作用目标为方法或类型。被标注的方法仅限服务之间内部调用。
示例
@CrossOrigin
@RestController
@Tag(name = "系统:基础服务")
@Tag(name = "领域:认证授权")
@Tag(name = "职责:查询操作")
@Tag(name = "实体:认证授权")
public class UserTokenQueryController extends AbstractRestController implements UserTokenQueryApi {
@Override
@ServerInternalAccessOnly
@Operation(summary = "检查用户令牌是否可用", hidden = true)
public Boolean available(@Parameter(description = "用户令牌 ID") String tokenId) {
return userTokenQueryService.available(tokenId);
}
...
}
@ValidateCaptcha
说明
人机验证码校验注解,作用目标为需要进行人机验证的方法。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
required | 用于标明注解所修饰的接口是否必须进行人机验证 | true |
passWhenParameterNotPresent | 存在指定的属性时不进行校验 | |
credentialParameters | 用户凭证属性 |
示例
@CrossOrigin
@RestController
@Tag(name = "系统:基础服务")
@Tag(name = "领域:认证授权")
@Tag(name = "职责:认证授权")
@Tag(name = "实体:认证授权")
public class AuthenticationController extends AbstractRestController implements AuthenticationApi {
@Override
@Operation(summary = "认证授权")
// 若设定了密码则使用登录用户名检查是否必须识别图形验证码,并在必须识别时校验图形验证码
@ValidateCaptcha(
required = false,
passWhenParameterNotPresent = {
@ValidateCaptcha.Parameter(type = AuthenticationDTO.class, propertyName = "password")
},
credentialParameters = {@ValidateCaptcha.Parameter(type = AuthenticationDTO.class, propertyName = "username")}
)
// 若未设定密码则校验电子邮件或短信验证码
@ValidateVerificationCode(
value = VerificationPurpose.USER_SIGN_IN,
passWhenParameterPresent = {
@ValidateVerificationCode.Parameter(type = AuthenticationDTO.class, propertyName = "password")
}
)
public AuthorizationDTO authenticate(@Valid AuthenticationDTO authenticationDTO) throws IOException {
try {
return authenticationService.authenticate(getOperator(), authenticationDTO);
} catch (AuthenticationError e) {
captchaCountDownEventPublisher.publish(this,
new CaptchaClientDTO(authenticationDTO.getUsername(), getOperator().getRemoteAddress()));
throw e;
}
}
...
}
@ValidateVerificationCode
说明
短信/电子邮件验证码检查注解,作用目标为需要验证短信/电子邮件验证码的方法。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
value | 验证码用途 | |
keyParameterNames | 验证 KEY(电子邮箱地址/手机号码)的参数名称 | |
passWhenParameterPresent | 存在指定的属性时不进行校验 |
示例
@CrossOrigin
@RestController
@Tag(name = "系统:基础服务")
@Tag(name = "领域:认证授权")
@Tag(name = "职责:认证授权")
@Tag(name = "实体:认证授权")
public class AuthenticationController extends AbstractRestController implements AuthenticationApi {
@Override
@Operation(summary = "认证授权")
// 若设定了密码则使用登录用户名检查是否必须识别图形验证码,并在必须识别时校验图形验证码
@ValidateCaptcha(
required = false,
passWhenParameterNotPresent = {
@ValidateCaptcha.Parameter(type = AuthenticationDTO.class, propertyName = "password")
},
credentialParameters = {@ValidateCaptcha.Parameter(type = AuthenticationDTO.class, propertyName = "username")}
)
// 若未设定密码则校验电子邮件或短信验证码
@ValidateVerificationCode(
value = VerificationPurpose.USER_SIGN_IN,
passWhenParameterPresent = {
@ValidateVerificationCode.Parameter(type = AuthenticationDTO.class, propertyName = "password")
}
)
public AuthorizationDTO authenticate(@Valid AuthenticationDTO authenticationDTO) throws IOException {
try {
return authenticationService.authenticate(getOperator(), authenticationDTO);
} catch (AuthenticationError e) {
captchaCountDownEventPublisher.publish(this,
new CaptchaClientDTO(authenticationDTO.getUsername(), getOperator().getRemoteAddress()));
throw e;
}
}
...
}
单元测试
@CsvHeader
说明
作用目标为类型或方法。标明单元测试数据源的 CSV 数据头。
参数定义
参数名 | 说明 | 默认值 |
---|---|---|
fromColumn | 起始列索引 | 0 |
parameter | 测试方法参数在参数列表中的索引 | |
propertyNames | CSV 头名称数组 |
示例
@ParameterizedTest
@DisplayName("组织认证 - 认证成功")
@CsvHeader(
fromColumn = 2,
parameter = 2,
propertyNames = {"certificateType", "certificateNo", "certificateList[;]", "remark"}
)
@CsvSource({
"00000000000000001, 1619417905692, BUSINESS_LICENSE, 11010605882235, 'photo1;photo2;photo3', 申请商户认证",
"00000000000000002, 1619417905692, IDENTITY_CARD, 110102202104135815, 'photo', 申请个人认证"
})
void givenNotSubmittedOrg_whenSubmit_thenSaveSubmittedOrg(String orgId, Long revision,
@CsvParameter OrganizationSubmitDTO submitDTO) {
...
}
@CsvParameter
说明
作用目标为方法参数。标明单元测试 CSV 数据参数。
示例
@ParameterizedTest
@DisplayName("组织认证 - 认证成功")
@CsvHeader(
fromColumn = 2,
parameter = 2,
propertyNames = {"certificateType", "certificateNo", "certificateList[;]", "remark"}
)
@CsvSource({
"00000000000000001, 1619417905692, BUSINESS_LICENSE, 11010605882235, 'photo1;photo2;photo3', 申请商户认证",
"00000000000000002, 1619417905692, IDENTITY_CARD, 110102202104135815, 'photo', 申请个人认证"
})
void givenNotSubmittedOrg_whenSubmit_thenSaveSubmittedOrg(String orgId, Long revision,
@CsvParameter OrganizationSubmitDTO submitDTO) {
...
}