校验金额的必要性
开发过程中,经常会遇到上游系统传String类型的金额过来的情况。我们需要将之转换为Bigdecimal类型再计算或者保存到数据库。
如下图所示,若上游系统发送特殊符号过来就会报错。涉及到金额那可就不是小事啦。
校验方法
所以我们需要校验,如下代码所示,上游系统一般会将金额放到Map里面传过来,我们首先将Map转换为我们定义的request对象,然后对对象的属性进行注解校验。
public DecisionResponse fundOperationAccept(Map<String, Object> params) {
FundBankCommandOrderRequest request =
JSON.parseObject(JSON.toJSONString(params), FundBankCommandOrderRequest.class);
LOGGER.info("fundOperationAccept,request:{}", request);
DecisionResponse result = new DecisionResponse();
// 参数校验
fundOperationValidator.validateBankCommandOrder(request);
}
这里注入的Validator校验调用的包是javax.validation,下面代码是它的主要校验方法:
public class FundOperationValidator {
private static final Logger LOGGER = LoggerFactory.getLogger(FundOperationValidator.class);
@Autowired
private Validator validator;
/**
* 校验资金操作入参
* @param request
*/
public void validateFundOperation(FundOperationalOrderRequest request) {
LOGGER.info("validateFundOperation request{}", request);
//校验公共数据
Set<ConstraintViolation<FundOperationalOrderRequest>> validates = validator.validate(request);
Map<String, String> messageMap = BeanValidators.extractPropertyAndMessage(validates);
if (MapUtils.isNotEmpty(messageMap)) {
LOGGER.error("操作ID为{},操作类型为{}的资金操作下发失败,失败原因为{}",
request.getOperationId(), request.getOperationType(), messageMap.toString());
throw new AppException(CoreErrorCode.REQUEST_PARAM_VALIDATION_FALIURE, messageMap.toString());
}
LOGGER.info("validateFundOperation end");
}
}
public class BeanValidators {
/**
* 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.
*/
public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
Map<String, String> errorMessages = new HashMap<String, String>(CommonConstants.INITIAL_CAPACITY);
for (ConstraintViolation violation : constraintViolations) {
errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
}
return errorMessages;
}
我们在request对象的属性上加上@Pattern,该属性需要满足设置的正则表达式
/**
* 付款单金额,单位:元
*/
@Pattern(regexp = "^[0-9]+(.[0-9]{1,2})?$", message = "金额格式不对")
@NotBlank(message = "付款单金额不能为空")
@Length(max = 16, message = "付款单金额超过最大长度")
private String amount;
正则表达式思路
整数部分我们需要是0~9的数字,所以使用[0-9]
不能一个都没有,防止空字符串,所以使用[0-9]+
小数部分也是0~9的数字,且为1位或者2位,所以使用[0-9]+(.[0-9]{1,2})
小数部分也可能没有,所以使用[0-9]+(.[0-9]{1,2})?
^代表开始,&代表结束,最终得到:^[0-9]+(.[0-9]{1,2})?$
当然,有可能会出现上游传0开头的数字,比如03.22,这样的字符串,bigdecimal会自动去除前面的0,所以系统不会报错,此处我觉得没有必要校验这种情况。
如果还有其它不满足的情况,也请告诉我哈,PS:
某正则表达式测试网站:
版权声明:本文为zhuyacheneagle原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。