使用注解校验的正则方法校验金额

校验金额的必要性

开发过程中,经常会遇到上游系统传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:某正则表达式测试网站:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值