在开发中我们难免遇到1代表X1,2代表X2,3代表X3等这种业务类型的常量,在如今的微服务前后端完全分离的开发中,对接这些业务常量成了很棘手的问题。
eg: 在做第三方项目时有很多第三方公司自定义一些常量,比如道路级别:1-主要道路;2-次要道路;3-背街小巷",因为这个常量在很多子系统也用到,为了确保唯一性、数据库采用枚举类型、前端也要确保传入的也必须是1、2、3,可以利用自定义参数校验器来实现。实现如下:
一、数据库层面采用枚举类型
二、创建业务常量类
public interface BusinessTypeConstant {
/**
*道路级别:1-主要道路;2-次要道路;3-背街小巷
*/
String ROAD_LEVEL_MAIN = "1";//主要道路
String ROAD_LEVEL_MINOR = "2";//次要道路
String ROAD_LEVEL_ALLEY = "3";//背街小巷
}
三、 自定义注解
@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = BusinessTypeValidator.class)
@Documented
public @interface BusinessType {
String message() default "业务类型有误";
String[] value() default {};
int[] intValue() default {};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
ReturnCode returnCode() default ReturnCode.BUSINESS_TYPE_ERROR;
}
四、业务类型参数校验器实现注解参数校验
public class BusinessTypeValidator implements ConstraintValidator<BusinessType, Object> {
private String[] businessTypeValues;
private int[] intValue;
@Override
public void initialize(BusinessType businessType) {
businessTypeValues = businessType.value();
intValue = businessType.intValue();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext ctx) {
if (value == null) {
return true;
}
if (value instanceof String) {
for (int i = 0; i < businessTypeValues.length; i++) {
if (value.equals(businessTypeValues[i])) {
return true;
}
}
} else if (value instanceof Integer) {
for (int i = 0; i < intValue.length; i++) {
if (value.equals(intValue[i])) {
return true;
}
}
}
return false;
}
}
五、在前端传来入参时做校验
@ApiModelProperty(value = "道路级别:1-主要道路;2-次要道路;3-背街小巷", required = true)
@BusinessType({
BusinessTypeConstant.ROAD_LEVEL_MAIN,
BusinessTypeConstant.ROAD_LEVEL_MINOR,
BusinessTypeConstant.ROAD_LEVEL_ALLEY
})
String level;
六、当前端参数传来通不过时,会返回自定义注解里面的定义信息,可以继续封装返回的信息
总结: 这样就很方便的达到了目的、从前端传来的参数必须是制定的类型、存入数据库的数据或者导入数据库的数据也必须是这指定的类型、其它系统掉用也就完美解决了业务类型常量在各个子系统之间的统一性。