首页 > 编程知识 正文

java自定义注解实现数据校验(@valid嵌套校验)

时间:2023-05-05 14:49:55 阅读:68015 作者:4339

Springboot版本:2.3.1.RELEASE

dependencygroupidorg.spring framework.boot/groupidartifactidspring-boot-starter-validation/artifact id/dependent

用户请求体package com.study.bean.dto; import com.study.bean.voli date.ageadultcompare; import io.swagger.annotations.API模型; import io.swagger.annotations.apimodelproperty; 导入lombok.data; import javax.validation.constraints.max; import javax.validation.constraints.min; import javax.validation.constraints.not blank; import javax.validation.constraints.not null;/* * @ author curtain * @ date 2021/4/2615336034 * @ description */@data@APImodel (新用户请求体) ) ageadultcomparepubution @ not blank (消息='名称不能为空') apimodelproperty (名称=' name ) /**性别*/@ not blank (消息='性别不能为空) ) apimodelproperty (名称=' sex ',value='性别', required=true ) privataty /**年龄*/@ not null (消息='年龄不能为空') min ) value=0, 消息='年龄最低10岁') max ) value=1000消息='人类目前的年龄不超过1000岁') @apimodelproperty(name='age ',value=' ) /** * 0未成年1成人*/@ not null (消息='是否成人不能为空') apimodelproperty (名称=' adult ',value='0未成年1成人', required=true }其中,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 2021/4/2615336040 * @ description检查自定义评论、年龄和是否为成人*/@ documented @ retention (retention policy.runtime ) target ) elementtype.type ) constraint ) validatedby=) constraint put //以下两行非固定模板Class? [] groups () default { } ); Class? 扩展支付[ ]支付()默认值{ } ); }其中的AgeAdultValidator是我们创建的检查类,其中包含检查逻辑。

AgeAdultValidator pac

kage com.study.bean.volidate;import com.study.bean.dto.AddPersonParam;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;/** * @Author Curtain * @Date 2021/4/26 15:41 * @Description */public class AgeAdultValidator implements ConstraintValidator<AgeAdultCompare, Object> { @Override public 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 2021/4/26 15:49 * @Description */@RestController@RequestMapping("/api/v1")@Api(tags = "人员控制类")public class PersonController { @Resource private 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 2021/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); }}

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

最后附上一个测试结果图

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。