JAVA 自定义参数校验的一种方式

本文介绍了一种基于validation-api的参数验证方法,在Web项目中简化重复的参数校验逻辑。通过定义自定义注解和验证实现,可以高效地确保传入参数的有效性和格式正确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在web项目中,经常会通过Map进行接收参数进行查询,其中经常有这样的需求,需要对某个参数要验证必须有值,要验证某些参数的传参格式是否符合需要的类型。

经常是这样的实现:

@PostMapping(value = "/user/list") 
public String list(Map<String, Object> params) {
    Object userName = params.get("userName");
    
    if(userName == null || String.valueOf(userName).equal("")) {
        return "参数userName不能空"!   
    }
    
}
@PostMapping(value = "/role/list") 
public String list(Map<String, Object> params) {
      Object roleName = params.get("role");
    
    if(roleName == null || String.valueOf(roleName).equal("")) {
        return "角色名称不能为空"!   
    }
    
}

类似这样的一些列表进行查询的时候都需要参数进行校验,当有多这样的查询的时候都需要写相关的校验,这时就会显得很冗余,如何解决该类型的写法呢?

下面介绍项目中常用的一种实现,基于validation-api的验证。

定义检查类:

@Constraint(validatedBy = RequiredFieldCheckImpl.class)
@Target(value = {ElementType.PARAMETER})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface RequiredFieldCheck {

    /**
     * 拦截的字符串
     *
     * @return
     */
    String[] requiredField() default {};

    /**
     * 值类型.
     *
     * @return
     */
    String[] requiredFieldValueType() default {};

    /**
     * 验证不通过时的错误提示信息
     * @return
     */
    String message() default "参数值不能为空!";

    /**
     * 分组
     * @return
     */
    Class<?>[] groups() default {};

    /**
     * 负载
     * @return
     */
    Class<? extends Payload>[] payload() default {};

    /**
     * 分页页数
     * @return
     */
    int pageNum() default 1;

    /**
     * 分页条数
     * @return
     */
    int pageSize() default 10;


}

检查类的具体实现:

public class RequiredFieldCheckImpl implements ConstraintValidator<RequiredFieldCheck, Map<String, Object>> {

    private String[] required;
    private int pageSize;
    private int pageNum;
    //private String[] requiredType;
    private Map<String, String> fieldTypeMap;

    /**
     * 初始化
     *
     * @param constraintAnnotation
     */
    @Override
    public void initialize(RequiredFieldCheck constraintAnnotation) {
        this.required = constraintAnnotation.requiredField();
        this.pageNum = constraintAnnotation.pageNum();
        this.pageSize = constraintAnnotation.pageSize();
        String[] checkFieldType = constraintAnnotation.requiredFieldValueType();
        fieldTypeMap = new HashMap<>();

        for (String type : checkFieldType) {
            String[] tmps = type.split(":");
            fieldTypeMap.put(tmps[0], tmps[1]);
        }

        TopsecLogUtil.info("check field :" + ArrayUtil.join(required, ","));
    }

    /**
     * 检验逻辑
     *
     * @param value
     * @param context
     * @return
     */
    @Override
    public boolean isValid(Map<String, Object> value, ConstraintValidatorContext context) {

        if (ArrayUtil.isEmpty(required)) {
            return true;
        }
        if (CollUtil.isEmpty(value)) {
            bulidValidResult(context, ArrayUtil.join(required, ","));
            return false;
        }
        for (String each : required) {
            if (!value.containsKey(each) || StrUtil.isEmpty(value.get(each).toString())) {
                bulidValidResult(context, each);
                return false;
            }

          /*  if (fieldTypeMap.containsKey(each)) {
                if(!bulidParams(fieldTypeMap.get(each), value, each)) {
                    bulidValidTypeResult(context, each);
                    return false;
                }
            }*/
        }

        for(String key : fieldTypeMap.keySet()) {
            if(value.containsKey(key) && value.get(key) != null) {
                if(!bulidParams(fieldTypeMap.get(key), value, key)) {
                    bulidValidTypeResult(context, key);
                    return false;
                }
            }else {
                initParams(fieldTypeMap.get(key),value, key);
            }
        }


        if (!value.containsKey(Pages.pageNum.getName())) {
            value.put(Pages.pageNum.getName(), pageNum);
        }
        if (!value.containsKey(Pages.pageSize.getName())) {
            value.put(Pages.pageSize.getName(), pageSize);
        }
        return true;
    }

    private void initParams(String valueType, Map<String, Object> params, String field) {

        try {
            switch (valueType) {
                case "Long[]":
                    params.put(field, new Long[]{});
                    break;
                case "Long":
                    params.put(field, 0L);
                    break;
                case "String[]":
                    params.put(field, new String[]{});
                    break;

            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Boolean bulidParams(String valueType, Map<String, Object> params, String field) {

        try {
            switch (valueType) {
                case "Long[]":
                    List<Integer> clueIds = (List<Integer>)params.get(field);
                    Long[] clueIdsLong = new Long[clueIds.size()];
                    for(int i=0; i<clueIds.size(); i++) {
                        clueIdsLong[i] = clueIds.get(i).longValue();
                    }
                    params.put(field, clueIdsLong);
                    break;
                case "Long":
                    String value = String.valueOf(params.get(field));
                    params.put(field, Long.parseLong(value));
                    break;
                case "String[]":
                    List<String> strList = (List<String>)params.get(field);
                    String[] strArray = new String[strList.size()];
                    for(int i=0; i<strList.size(); i++) {
                        strArray[i] = strList.get(i);
                    }
                    params.put(field, strArray);
                    break;

            }

            return Boolean.TRUE;
        }catch (Exception e) {
            e.printStackTrace();
        }

        return Boolean.FALSE;
    }

    /**
     * 构建校验出错信息!
     *
     * @param context
     * @param message
     */
    private void bulidValidResult(ConstraintValidatorContext context, String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate("[" + message + "]参数不能为空!").addConstraintViolation();
    }

    /**
     * 构建校验出错信息!
     *
     * @param context
     * @param message
     */
    private void bulidValidTypeResult(ConstraintValidatorContext context, String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate("[" + message + "]值格式不对!").addConstraintViolation();
    }
}

用法: 类需要添加@Validated, requiredField 字段包括必填字段,requiredFieldValueType 字段是参数要求的类型

 @ApiOperation(value = "xxx列表", notes = "")
    @PostMapping(value = "/list")
    public void list(
            @RequestBody @RequiredFieldCheck(requiredField = {"pageNum", "pageSize"},
                    requiredFieldValueType={"tags:String[]"}) Map<String, Object> params) {

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值