基于springboot使用@validated注解

1.引入pom


            org.hibernate
            hibernate-validator
            6.0.13.Final
        

2.创建校验参数配置类HibernateValidatorConfiguration

package com.yinlian.bj.config;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import javax.validation.Validation;
import javax.validation.Validator;

/**
 * 参数校验Validator配置类
 *
 * @author: zds
 * @Date: 2019/9/2 10:59
 */
@Configuration
public class HibernateValidatorConfiguration {

    /**
     * JSR和Hibernate validator的校验只能对Object的属性进行校验
     * 不能对单个的参数进行校验
     * spring 在此基础上进行了扩展
     * 添加了MethodValidationPostProcessor拦截器
     * 可以实现对方法参数的校验
     *
     * @return
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        processor.setValidator(validator());
        return processor;
    }

    @Bean
    public static Validator validator() {
        return Validation
                .byProvider(HibernateValidator.class)
                .configure()
                //快速返回模式,有一个验证失败立即返回错误信息
                .failFast(true)
                .buildValidatorFactory()
                .getValidator();
    }
//
//    public static  void validate(T obj) {
//        Set> constraintViolations = validator().validate(obj);
//        if (constraintViolations.size() > 0) {
//            throw LogicException.le(constraintViolations.iterator().next().getMessage());
//        }
//    }

}

3.创建异常类

package com.yinlian.bj.exception;

/**
 * @author: zds
 * @Date: 2019/9/2 12:06
 */
public class ApiResultException extends RuntimeException{

    /**
     * 异常信息
     */
    private String errorMsg;
    /**
     * 错误码
     */
    private String code;

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    private ApiResultException(String errorMsg) {
        super(errorMsg);
        this.code = errorMsg.substring(0, 4);
        this.errorMsg = errorMsg.substring(5);
    }

    /**
     * 抛出逻辑异常
     *
     * @param errorMsg
     * @return
     */
    public static ApiResultException le(String errorMsg) {
        return new ApiResultException(errorMsg);
    }

}

4.创建接口返回类

package com.yinlian.bj.exception;

import com.yinlian.bj.util.DateJsonValueProcessor;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author: zds
 * @Date: 2019/9/2 11:17
 */
public class RestResult {

    private String startTime;
    private int code;
    private String desc;
    private Object data;
    private String token;

    public String toJson() {
        JSONObject json;
        JsonConfig config = new JsonConfig();
        config.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
        json = JSONObject.fromObject(this,config);
        return json.toString();
    }

    public RestResult() {
        this.data = "";
        this.desc = "";
        this.code = 0;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
        this.startTime = df.format(new Date());// new Date()为获取当前系统时间
        this.token = "";
    }

    public String getStartTime() {
        return startTime;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}

5.创建全局异常拦截器

package com.yinlian.bj.exception;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;

/**
 * @author: zds
 * @Date: 2019/9/2 11:13
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object logicExceptionHandler(HttpServletRequest request, Exception e, HttpServletResponse response) {
        RestResult result = new RestResult();
        //拦截validation验证的异常
        if (e instanceof ConstraintViolationException) {
            String message = ((ConstraintViolationException) e).getConstraintViolations().iterator().next().getMessage();
            result.setCode(Integer.parseInt(message.substring(0, 4)));
            result.setDesc(message.substring(5));
        } else if(e instanceof ApiResultException){ //拦截自定义异常
            ApiResultException apiResultException = (ApiResultException) e;
            result.setCode(Integer.parseInt(apiResultException.getCode()));
            result.setDesc(apiResultException.getErrorMsg());
        } else {//拦截总异常
            logger.error("系统异常:" + e.getMessage(), e);
            result.setCode(-900);
            result.setDesc("系统异常");
        }
        return result.toJson();
    }

}


6.创建接口返回值拦截

package com.yinlian.bj.exception;

import com.alibaba.fastjson.JSONObject;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author: zds
 * @Date: 2019/9/2 11:29
 */
 //需要拦截返回值的package路径
@ControllerAdvice(basePackages = "com.yinlian.bj.controller.api")
public class RestResultWrapper implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//        RestResult result = new RestResult(0,"成功",body);
//        return result.toJson();
        return body;
    }
}

 
  

7.控制器调用

package com.yinlian.bj.controller.api;

import com.yinlian.bj.dto.SessionUser;
import com.yinlian.bj.dto.api.ApiAddressBookPro;
import com.yinlian.bj.dto.api.ApiBookUserInfoDto;
import com.yinlian.bj.exception.ApiResultException;
import com.yinlian.bj.exception.RestItem;
import com.yinlian.bj.exception.RestResult;
import com.yinlian.bj.interceptor.PageBean;
import com.yinlian.bj.po.AddressBook;
import com.yinlian.bj.search.api.ApiCriteriaAddressBook;
import com.yinlian.bj.search.api.ApiCriteriaComment;
import com.yinlian.bj.service.AddressBookService;
import com.yinlian.bj.util.BaseResult;
import com.yinlian.bj.util.ReusltItem;
import com.yinlian.bj.util.SessionState;
import com.yinlian.bj.util.StringUtilsEX;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.ConstraintViolationException;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import java.util.Date;
import java.util.List;

/**
 * 通讯录Controller
 *
 * @author: zds
 * @Date: 2019/8/26 14:52
 */
@RestController
@RequestMapping("/api/app/addressbook")
@Validated
public class ApiAddressBookController {

    private static final Logger logger = LoggerFactory.getLogger("monitor");

    @Autowired
    private SessionState sessionState;
    @Autowired
    private AddressBookService addressBookService;

    @RequestMapping(value = "/remind", produces = "text/html;charset=UTF-8")
    public String remind(
            @NotNull(message = "-401_请先登录") String token,
            @DecimalMin(value = "0", message = "-101_通讯录id参数错误") @NotNull(message = "-101_通讯录id参数错误") String id) throws Exception {
        RestResult restResult = new RestResult();
        SessionUser sessionUser = sessionState.GetCurrentUser(token);
        if (sessionUser.getCode() != 0) {
            throw ApiResultException.le("-401_请先登录");
        }
        AddressBook addressBook = addressBookService.getAddressBookById(StringUtilsEX.ToInt(id));
        if (addressBook == null) {
            throw ApiResultException.le("-102_未查询到信息");
        }
        if (!addressBook.getBuyerid().equals(sessionUser.getUserId())) {
            throw ApiResultException.le("-103_无权限");
        }
        if (addressBookService.updateRemind(StringUtilsEX.ToInt(id)) > 0) {
            restResult.setDesc("成功");
            restResult.setCode(0);
            return restResult.toJson();
        } else {
            throw ApiResultException.le("-200_提醒失败");
        }
    }

}

不要忘记才controller加@Validated注解

8. 部分标签含义

限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

你可能感兴趣的:(java,springboot,@validated)