如何优雅的对后端接口参数校验

430 阅读2分钟

1 前言

      后端如何优雅的对接口参数做校验,在开发过程中由于前端的一切输入都是不可信的,所以后端需要对前端的请求参数进行二次校验的。例如我们保存表单数据时候,这里的客户名称需要必填、手机号格式要正确,前端虽然做了校验,但是后端的校验也是必不可少的。因为用户可能修改我们的前端校验规则绕过前端校验。 

2 验证框架

      Spring Boot为我们后端提供了一个很强大的参数验证框架validation,它可以对我们的实体类字段进行校验,并且可以给我们提供详细的错误提示信息,使用过程也非常优雅。 

3 使用步骤 

1 在 pom.xml 文件中添加以下依赖

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

2 在实体类中字段属性添加验证规则注解

@Size(max=64)
@NotEmpty(message = "客户姓名不能为空")
private String name;

说明:在实体类中使用注解,可以指定当前字段是否可以为 null,以及字符串的长度和格式等信息,如果传入的参数不符合预定的规则,在校验时就会产生相应的提示。

常用的参数验证注解:

@Digits:验证注解字段的整数位数和小数位数是否符合预期;

@Email:验证注解的字段是否为Email格式。

@Max Min 字段最大最小值

@NotBlank:验证注解的字段不为null,且允许去除两端空格后不为空;

@NotEmpty:验证注解的字段不为null,且String类型也不为 "";

@NotNull:验证注解的字段不为null;

3 在Controller中对接口参数添加验证注解 @Valid

@RequiresPermissions("crm:memberBase:update")
@ResponseBody@RequestMapping("/save.json")
public ResponseObj<Boolean> save(@Valid @RequestBody MemberBase bean) {
    return success(memberBaseApi.saveOrUpdate(getTenantId(),bean,getUsername()));
}

4 定义全局异常处理器,封装返回结果(demo)

@ControllerAdvice
@RestController
public class WebExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public Object handleException(Exception e) {
        if(e instanceof BusinessException) {
            BusinessException error = (BusinessException)e;
            logger.warn(error.getMsg());
            return rendError(new BaseCode(error.getCode(),error.getMsg()));
        }
        else if(e instanceof MethodArgumentNotValidException) {
            BindingResult result = ((MethodArgumentNotValidException)e).getBindingResult();
            FieldError error = result.getFieldError();
            logger.warn("请求参数错误:{}",error.getDefaultMessage());
            return rendError(BaseCode.ERR_PARAMS_VALID,error.getDefaultMessage());
        }
        logger.error("系统错误:{}",e.getMessage(), e);
        return rendError(BaseCode.ERROR);
    }
    
}

完成以上步骤后,后端校验就完成了。

4 自定义注解

如果validation框架 提供的校验规则不能满足我们的业务。我们也可以采用自定义注解和验证器的方式进行参数验证。比如,我们可以自定义校验注解对手机号格式进行校验。

1 自定校验器示例代码如下:

package com.mrxu.framework.boot.validation;

import cn.hutool.core.util.PhoneUtil;
import com.mrxu.framework.common.util.StrFunc;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;

public class MobileValidator implements ConstraintValidator<MobileValidator.Mobile,String> {

    @Override
    public void initialize(Mobile constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(StrFunc.isNotEmpty(value)) {
            return PhoneUtil.isMobile(value);
        }
        return true;
    }

    @Target({ElementType.FIELD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Constraint(validatedBy = {MobileValidator.class})
    public @interface Mobile {
        String message() default "手机号格式错误";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
}

2 使用时,我们在实体类字段上添加我们的注解

@MobileValidator.Mobile(message = "您手机号输错了")
private String mobile;

分享的内容如果对你有用记得点赞关注