1.引入pom
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
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 <T> void validate(T obj) {
// Set<ConstraintViolation<T>> 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<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> 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,也可以通过正则表达式和flag指定自定义的email格式 |