900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 使用validate注解做校验以及自定义validate注解

使用validate注解做校验以及自定义validate注解

时间:2022-11-03 21:33:38

相关推荐

使用validate注解做校验以及自定义validate注解

Springboot版本:2.3.1.RELEASE

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

ps:Springboot版本在2.3一下的引用的是别的依赖,可以查一下。

新增用户请求体

package com.study.bean.dto;import com.study.bean.volidate.AgeAdultCompare;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import javax.validation.constraints.Max;import javax.validation.constraints.Min;import javax.validation.constraints.NotBlank;import javax.validation.constraints.NotNull;/*** @Author Curtain* @Date /4/26 15:34* @Description*/@Data@ApiModel("新增用户请求体")@AgeAdultComparepublic class AddPersonParam {/*** 姓名*/@NotBlank(message = "姓名不能为空")@ApiModelProperty(name = "name", value = "姓名", required = true)private String name;/*** 性别*/@NotBlank(message = "性别不能为空")@ApiModelProperty(name = "sex", value = "性别", required = true)private String sex;/*** 年龄*/@NotNull(message = "年龄不能为空")@Min(value = 0, message = "年龄最小为10岁")@Max(value = 1000, message = "人类目前年龄超不过1000岁")@ApiModelProperty(name = "age", value = "年龄", required = true)private Integer age;/*** 0未成年1成年*/@NotNull(message = "是否成年不能为空")@ApiModelProperty(name = "adult", value = "0未成年1成年", required = true)private Integer adult;}

这里涵盖了validate注解中的@NotNull、@NotBlank、@Min、@Max还有个自定义的validate注解@AgeAdultCompare。

除了自定义的validate注解以外,其他的几个注解想必大家一眼就能看出来是什么意思,这里就不再赘述。

自定义的@AgeAdultCompare注解

作用:用来校验年龄和是否成年这两个字段是否相对应(年龄大于18必须是成年,年龄小于18必须是未成年)

首先是定义一个validate类型的注解

package com.study.bean.volidate;import javax.validation.Constraint;import javax.validation.Payload;import java.lang.annotation.*;/*** @Author Curtain* @Date /4/26 15:40* @Description 自定义注解,校验年龄和是否成年*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Constraint(validatedBy = AgeAdultValidator.class)public @interface AgeAdultCompare {//校验未通过时的返回信息String message() default "年龄和是否成年要相对应";//以下两行未固定模板Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };}

其中的AgeAdultValidator就是我们要创建的校验类,里面写的是校验逻辑.

AgeAdultValidator

package com.study.bean.volidate;import com.study.bean.dto.AddPersonParam;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;/*** @Author Curtain* @Date /4/26 15:41* @Description*/public class AgeAdultValidator implements ConstraintValidator<AgeAdultCompare, Object> {@Overridepublic boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {if (o instanceof AddPersonParam){AddPersonParam param = (AddPersonParam) o;if (param.getAge() != null && param.getAdult() != null){if (param.getAge() > 17 && param.getAdult() == 0)return false;if (param.getAge() < 17 && param.getAdult() == 1)return false;}}return true;}}

这些都写完之后,我们要在接口上面的请求参数前加上@valid注解就完事了

package com.study.web.controller;import com.study.bean.dto.AddPersonParam;import com.study.bean.response.ResultBody;import com.study.service.api.db01.PersonService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import javax.validation.Valid;/*** @Author Curtain* @Date /4/26 15:49* @Description*/@RestController@RequestMapping("/api/v1")@Api(tags = "人员控制类")public class PersonController {@Resourceprivate PersonService personService;@PostMapping("/person")@ApiOperation(value = "新增人员", notes = "新增人员")ResultBody addPerson(@RequestBody @Valid AddPersonParam addPersonParam){return ResultBody.success(personService.add(addPersonParam));}}

测试接口的时候,不符合我们注解的要求都会抛出一个叫做MethodArgumentNotValidException的异常。

如果我们想把我们在validate相关注解中的message信息返回给调用的人,我们可以定义一个全局的异常捕获。

全局异常捕获类

package com.study.web.config;import com.study.bean.enums.ResponseEnum;import com.study.bean.exception.ApiException;import com.study.bean.response.ResultBody;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolationException;import java.util.stream.Collectors;@RestControllerAdvicepublic class GlobalExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 捕获全局入参错误异常* @param e* @return*/@ExceptionHandler(MethodArgumentNotValidException.class)public ResultBody handleGlobalException(MethodArgumentNotValidException e){return ResultBody.error(e.getBindingResult().getAllErrors().stream().map(a -> a.getDefaultMessage()).collect(Collectors.joining(",")));}}

这里的ResultBody是我自己写的一个返回实体类。

ResultBody

package com.study.bean.response;import com.study.bean.enums.ResponseEnum;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;/*** @Author Curtain* @Date /4/15 20:12* @Description*/@Getter@Setter@AllArgsConstructor@NoArgsConstructorpublic class ResultBody<T> {/*** 状态码*/private String code;/*** 状态信息*/private String message;/*** 接口返回数据*/private T result;public static ResultBody success(){return success(null);}public static <T> ResultBody<T> success(T o) {ResultBody resultBody = new ResultBody(ResponseEnum.SUCCESS);resultBody.setResult(o);return resultBody;}public static ResultBody error(String code, String message){return new ResultBody(code, message, null);}public static ResultBody error(String message){return new ResultBody("-1", message, null);}}

可以根据自己的需求删减和补充。

最后附上一个测试结果图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。