使用 hibernate 的 validator 校验器验证

spring boot 虽然集成了 valid 验证,但是只是针对单个参数,不能是整个类,这时就可以使用 hibernate 的 validator 验证器,而且有分组的功能,例如:在注册时要验证 A 类三个字段,但在登录时只需要验证 A  类的两个字段,如果要另外创建一个 VO 类就很没必要,这时就可以使用分组来解决

 

1、创建一个验证的工具类

package io.xiongdi.common.validator;

import io.xiongdi.common.exception.XDException;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;


/**
 * @author wujiaxing
 * @date 2019-07-07
 * <p>
 *     hibernate-validator校验工具类
 *     可以参考 http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
 * </p>
 */
public class ValidatorUtils {
    /**
     * 验证器
     */
    private static Validator validator;

    static {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    /**
     *  验证方法
     *  <p>
     *      同一个pojo类,可能会被多个controller使用验证,而每个controller的验证规则有不同,
     *      这是就需要分组验证,其实就是几个要分组的空接口,指定属性A属于哪个组,属性B又属于
     *      哪个组,这样在controller验证时就指定我要验证哪个组
     *  </p>
     * @param object 被校验的对象
     * @param groups 被校验的组
     * @throws XDException 校验不通过抛出自定义异常
     */
    public static void validateEntity(Object object, Class<?>... groups) throws XDException{
        // 用验证器执行验证,返回一个违反约束的set集合
        Set<ConstraintViolation<Object>> violationSet = validator.validate(object, groups);
        // 判断是否为空,空:说明验证通过,否则就验证失败
        if(!violationSet.isEmpty()) {
            // 获取第一个验证失败的属性
            ConstraintViolation<Object> violation = violationSet.iterator().next();
            // 抛出自定义异常
            throw new XDException(violation.getMessage());
        }

    }
}

 

2、定义验证的 VO 类,hibernate 定义了很多的注解,可自行查阅,这里只使用了 @NotBlank

package io.xiongdi.form;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotBlank;

/**
 * 登录表单
 * @author wujiaxing
 * @date 2019-06-30
 */
@Data
@ApiModel(value = "登录表单")
public class LoginForm {

    @ApiModelProperty(value = "手机号")
    @NotBlank(message = "手机号不能为空")
    private String mobile;

    @ApiModelProperty(value = "密码")
    @NotBlank(message = "密码不能为空")
    private String password;
}

 

3、从 Controller 中调用验证工具方法执行验证

package io.xiongdi.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.xiongdi.annotation.Login;
import io.xiongdi.common.utils.R;
import io.xiongdi.common.validator.ValidatorUtils;
import io.xiongdi.form.LoginForm;
import io.xiongdi.service.TokenService;
import io.xiongdi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Map;

/**
 * @author wujiaxing
 * @date 2019-07-07
 */
@Api(tags = "登录接口")
@RequestMapping("/api")
@RestController
public class ApiLoginController {

    @Autowired
    private TokenService tokenService;
    @Autowired
    private UserService userService;

    @RequestMapping("login")
    @ApiOperation("登录")
    public R login(@RequestBody  LoginForm loginForm) {
        // 服务端表单校验
        System.out.println("已进入login"+loginForm);
        ValidatorUtils.validateEntity(loginForm); // 在这里调用了
        // 执行登录
        Map<String, Object> map = userService.login(loginForm);

        return R.ok(map);
    }

    /**
     * <p>
     *     登出需要请求中带token
     *     @RequestAttribute 这个注解表示访问有过滤器或拦截器创建的、预先存在的属性
     * </p>
     * @param userId
     * @return
     */
    @Login
    @ApiOperation("登出")
    @RequestMapping("logout")
    public R logout(@RequestAttribute("userId") @ApiIgnore long userId) {
        tokenService.expireToken(userId);
        return R.ok();
    }
}

 

到现在就已经配置成功了,是不是很简单呢

posted @ 2019-07-13 22:30  渣男梦想  阅读(4020)  评论(0编辑  收藏  举报