Springboot checks the parameters

Table of contents


When the controller layer receives the data from the front end, we need to conduct a unified inspection of the parameters, such as checking whether the mobile phone number is empty and whether the format is correct when logging in, and also needs to return the verification information, so how to design this part?

In response to this problem, Java developers defined the standard validation-api for Bean validation in the Java API Specification (JSR303) , but did not provide an implementation. hibernate validation is the implementation of this specification, and adds validation annotations such as @Email, @Length, etc. Spring Validation is a secondary encapsulation of hibernate validation , used to support automatic validation of spring mvc parameters. Next, we introduce the use of Spring Validation.

@Valid

  • Step 1: Add dependencies
        <!-- hibernate 验证框架 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
  • Step 2: Encapsulate parameters
    Encapsulate the user's parameters passed from the front end into the custom entity RegistLoginBO, and add annotation constraints and message to each parameter field
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class RegistLoginBO {
    
    

    @NotBlank(message = "手机号不能为空")
    @Length(min = 11, max = 11, message = "手机长度不正确")
    private String mobile;
    @NotBlank(message = "验证码不能为空")
    private String verifyCode;

}
  • Step 3: Controller obtains the parameters.
    By @Valid @RequestBody RegistLoginBO registLoginBOverifying the parameters, if the parameters are incorrect and throwing MethodArgumentNotValidException, @ControllerAdvice + @ExceptionHandler(MethodArgumentNotValidException.class)the exception will be caught uniformly. The value of the parameter verification is placed in the BindingResult, which can be obtained through e.getBindingResult().
    @PostMapping("login")
    public GraceJSONResult login(@Valid @RequestBody RegistLoginBO registLoginBO) throws Exception {
    
    


        String mobile = registLoginBO.getMobile();
        String code = registLoginBO.getSmsCode();

        // 1. 从redis中获得验证码进行校验是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        if (StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)) {
    
    
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        // 2. 查询数据库,判断用户是否存在
        Users user = userService.queryMobileIsExist(mobile);
        if (user == null) {
    
    
            // 2.1 如果用户为空,表示没有注册过,则为null,需要注册信息入库
            user = userService.createUser(mobile);
        }

        // 3. 如果不为空,可以继续下方业务,可以保存用户会话信息
        String uToken = UUID.randomUUID().toString();
        redis.set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);

        // 4. 用户登录注册成功以后,删除redis中的短信验证码
        redis.del(MOBILE_SMSCODE + ":" + mobile);

        // 5. 返回用户信息,包含token令牌
        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(user, usersVO);
        usersVO.setUserToken(uToken);

        return GraceJSONResult.ok(usersVO);
    }
  • check result
    insert image description here

@Validated

If a parameter UserParam can be used as a parameter of two methods, one of which is allowed to be null and the other is not required to be null, then @Validated group verification is required.

@ValidatedProvides a grouping function, which can adopt different verification mechanisms according to different groups when entering parameters; it can be used on types, methods and method parameters, but cannot be used on member attributes .

@ValidAs a standard JSR-303 specification, there is no function of absorbing grouping; it can be used on methods, constructors, method parameters and member attributes.

  • Define groups (no need to implement interfaces)
public interface AddValidationGroup {
    
    
}
public interface EditValidationGroup {
    
    
}
  • Check field add grouping
@Data
@Builder
@ApiModel(value = "User", subTypes = {
    
    AddressParam.class})
public class UserParam implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

    @NotEmpty(message = "{user.msg.userId.notEmpty}", groups = {
    
    EditValidationGroup.class}) // 这里
    private String userId;

}

  • The interface in the controller uses grouping when using verification
@Slf4j
@Api(value = "User Interfaces", tags = "User Interfaces")
@RestController
@RequestMapping("/user")
public class UserController {
    
    

    /**
     * http://localhost:8080/user/add .
     *
     * @param userParam user param
     * @return user
     */
    @ApiOperation("Add User")
    @ApiImplicitParam(name = "userParam", type = "body", dataTypeClass = UserParam.class, required = true)
    @PostMapping("add")
    public ResponseEntity<UserParam> add(@Validated(AddValidationGroup.class) @RequestBody UserParam userParam) {
    
    
        return ResponseEntity.ok(userParam);
    }

    /**
     * http://localhost:8080/user/add .
     *
     * @param userParam user param
     * @return user
     */
    @ApiOperation("Edit User")
    @ApiImplicitParam(name = "userParam", type = "body", dataTypeClass = UserParam.class, required = true)
    @PostMapping("edit")
    public ResponseEntity<UserParam> edit(@Validated(EditValidationGroup.class) @RequestBody UserParam userParam) {
    
    
        return ResponseEntity.ok(userParam);
    }
}

Custom validation

How to verify according to self-defined rules?

  • custom annotation
package tech.pdai.springboot.validation.group.validation.custom;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({
    
     METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {
    
    TelephoneNumberValidator.class}) // 指定校验器
public @interface TelephoneNumber {
    
    
    String message() default "Invalid telephone number";
    Class<?>[] groups() default {
    
     };
    Class<? extends Payload>[] payload() default {
    
     };
}
  • define validator
public class TelephoneNumberValidator implements ConstraintValidator<TelephoneNumber, String> {
    
    
    private static final String REGEX_TEL = "0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|13[0-9]\\d{8}|15[1089]\\d{8}";

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
    
    
        try {
    
    
            return Pattern.matches(REGEX_TEL, s);
        } catch (Exception e) {
    
    
            return false;
        }
    }

}

The following can be used normally to add validation constraints.

Guess you like

Origin blog.csdn.net/weixin_44153131/article/details/129011498