【参数校验参考】参数校验

http请求时,对参数进行校验,以post请求为例,直接上代码:

Maven 依赖

     <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-validator</artifactId>
         <version>6.0.18.Final</version>
     </dependency>

自定义注解

自定义注解切面
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * 自定义validation注册校验所传入内容必须在list中
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//指定校验规则 即注解校验规则
@Constraint(validatedBy = {InListValidator.class})
public @interface InList {
    String[] value() default {};

    String message() default "{params not found in InList value}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
自定义注解实现
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;

/**
 * InList校验逻辑
 */
class InListValidator implements ConstraintValidator<InList, String> {
    private List<String> valueList;

    @Override
    public void initialize(InList constraintAnnotation) {
        valueList = Arrays.asList(constraintAnnotation.value());
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        return valueList.contains(value);
    }
}
请求参数VO
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.math.BigDecimal;


@Data
public class RequestVO {

    @NotEmpty(message = "单号不能为空")
    private String bizOrderNo;

    @DecimalMin(value = "0", message = "账单金额不能小于0")
    private BigDecimal amount;

    private Integer id;

    @NotBlank(message = "昵称不能为空")
    @Length(min=1, max=3)
    private String nickname;

    @InList(value = {"1", "2"}, message = "类型必须为1、2")
    private String type;

}

Hibernate Validator常用注解

注解释义
@Null必须为null
@NotNull不能为null
@AssertTrue必须为true
@AssertFalse必须为false
@Min必须为数字,其值大于或等于指定的最小值
@Max必须为数字,其值小于或等于指定的最大值
@DecimalMin必须为数字,其值大于或等于指定的最小值
@DecimalMax必须为数字,其值小于或等于指定的最大值
@Size集合的长度
@Digits必须为数字,其值必须再可接受的范围内
@Past必须是过去的日期
@Future必须是将来的日期
@Pattern必须符合正则表达式
@Email必须是邮箱格式
@Length长度范围
@NotEmpty不能为null,长度大于0
@Range元素的大小范围
@NotBlank不能为null,字符串长度大于0(限字符串)

使用示例

代码调用示例,使用**@Valid注解**:

@RestController
@RequestMapping("/index")
public class IndexController {

    @PostMapping("test")
    public String test(@Valid @RequestBody RequestVO requestVO) {
        return requestVO.toString();
    }
}
代码测试示例

使用一下请求参数进行postman进行访问

{"amount":1000,"bizOrderNo":"bizno","id":10,"nickname":"昵称","type":"3"}
测试结果

结果如下:

{
    "timestamp": "2020-08-26T10:00:01.445+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "InList.requestVO.type",
                "InList.type",
                "InList.java.lang.String",
                "InList"
            ],
            "arguments": [
                {
                    "codes": [
                        "requestVO.type",
                        "type"
                    ],
                    "arguments": null,
                    "defaultMessage": "type",
                    "code": "type"
                },
                [
                    "1",
                    "2"
                ]
            ],
            "defaultMessage": "类型必须为1、2",
            "objectName": "requestVO",
            "field": "type",
            "rejectedValue": "3",
            "bindingFailure": false,
            "code": "InList"
        }
    ],
    "message": "Validation failed for object='requestVO'. Error count: 1",
    "path": "/index/test"
}

我们真正所需要的信息其实是:类型必须为1、2"

统一处理异常

将返回的数据统一封装,返回给前端的时候给3种信息,code、message以及data,约定code为指定code时,接口响应成功,data为响应数据

统一处理异常代码
import com.wanli.databoard.vo.BaseDataVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


@Slf4j
@ControllerAdvice
public class ExceptionAspect {
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public BaseDataVO notValidExceptionHandler(MethodArgumentNotValidException e) {
        String msg;
        if (!CollectionUtils.isEmpty(e.getBindingResult().getAllErrors())) {
            msg = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        } else {
            msg =  e.getMessage();
        }
        log.warn("接口参数校验未通过: {}", msg);
        return buildClientErrorVO(400, msg);
    }

    //errorCode 参数可以根据场景使用一个枚举来维护,枚举包含两个属性errorCode,message
    private static BaseDataVO buildClientErrorVO(int errorCode, String message) {
        return buildBaseData(errorCode, message);
    }

    private static BaseDataVO buildBaseData(int errorCode, String message) {
        BaseDataVO result = new BaseDataVO();
        result.setCode(errorCode);
        result.setData(null);
        result.setMessage(message);
        return result;
    }
}
测试结果

请求结果如下所示:
在这里插入图片描述

统一封装代码

Controller统一封装返回参数代码如下:

@RestController
@RequestMapping("/index")
public class IndexController{
    @PostMapping("test")
    public BaseDataVO test(@Valid @RequestBody RequestVO requestVO) {
        return successModel(requestVO);
    }

    private BaseDataVO successModel(Object data) {
        return new BaseDataVO()
                .setCode(200)
                .setData(data)
                .setMessage("Success");
    }
}
统一返回VO类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Accessors(chain = true)
public class BaseDataVO {
    private Integer code;
    private Object data;
    private String message;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值