新建SpringBoot项目引入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
新建Bean文件
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
/**
* 用户
*
* @author Tortoise
* @since 2019-04-16
**/
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
private Long id;
@NotBlank
@Length(max = 64)
private String name;
}
新建全局返回对象
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.util.Objects;
/**
* 返回对象
*
* @author Tortoise
* @since 2019-04-16
**/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Response<T> implements Serializable {
private static final long serialVersionUID = 1L;
public static final Integer SUCCESS = 200;
public static final Integer FAILED = 500;
/**
* 响应代码
*/
protected Integer code;
/**
* 响应消息
*/
protected String msg;
/**
* 响应数据
*/
protected T data;
/**
* 成功
*
* @param data 消息
* @param <T> 返回数据类型
* @return Response
*/
public static <T> Response<T> success(T data) {
return new Response<>(SUCCESS , "操作成功", data);
}
/**
* 成功
*
* @param msg 消息
* @param data 数据
* @param <T> 返回数据类型
* @return Response
*/
public static <T> Response<T> success(String msg, T data) {
return new Response<>(SUCCESS , msg, data);
}
/**
* 失败
*
* @param code 数据
* @param msg 消息
* @return Response
*/
public static <T> Response<T> failed(int code, String msg) {
return new Response<>(code, msg, null);
}
/**
* 失败
*
* @param code 数据
* @param msg 消息
* @param <T> 返回数据类型
* @return Response
*/
public static <T> Response<T> failed(int code, String msg,T data) {
return new Response<>(code, msg, data);
}
/**
* 判断响应结果是否成功
*
* @return true:成功,false:失败
*/
public boolean isSuccess() {
if (Objects.isNull(code)) {
return false;
}
return Objects.equals(SUCCESS , code);
}
}
新建Controller文件
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* 控制器
*
* @author Tortoise
* @since 2019-04-16
**/
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public Response<User> insert(@Valid User user) {
return Response.success(user);
}
}
新建异常转换类
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 全局参数校验异常信息
*
* @author Tortoise
* @since 2019-04-16
*/
@Data
@NoArgsConstructor
public class ValidateErrors implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 全局错误
*/
private List<String> globalErrors;
/**
* 字段错误
*/
private Map<String, String> fieldErrors;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Errors errors;
private List<String> globalErrors;
private Map<String, String> fieldErrors;
public Builder errors(Errors errors) {
this.errors = errors;
return this;
}
public Builder globalErrors(List<String> globalErrors) {
this.globalErrors = globalErrors;
return this;
}
public Builder fieldErrors(Map<String, String> fieldErrors) {
this.fieldErrors = fieldErrors;
return this;
}
public ValidateErrors build() {
ValidateErrors validateErrors = new ValidateErrors();
if (errors != null) {
if (errors.hasGlobalErrors()) {
validateErrors.setGlobalErrors(new LinkedList<>());
for (ObjectError error : errors.getGlobalErrors()) {
String message = error.getDefaultMessage();
validateErrors.getGlobalErrors().add(message);
}
}
if (errors.hasFieldErrors()) {
validateErrors.setFieldErrors(new HashMap<>(errors.getFieldErrors().size()));
for (FieldError error : errors.getFieldErrors()) {
String message = error.getDefaultMessage();
validateErrors.getFieldErrors().put(error.getField(), message);
}
}
}
if (fieldErrors != null) {
validateErrors.fieldErrors = fieldErrors;
}
if (globalErrors != null) {
validateErrors.globalErrors = globalErrors;
}
return validateErrors;
}
}
}
新建全局异常拦截配置
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.WebExchangeBindException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 异常配置
*
* @author Tortoise
* @since 2019-04-16
**/
@Slf4j
@ControllerAdvice
public class ExceptionConfig {
/**
* 对象参数验证异常
*
* @param e 异常
* @return 异常信息
*/
@ResponseBody
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Response methodArgumentNotValidException(MethodArgumentNotValidException e) {
return Response.failed(Response.FAILED, "对象参数验证异常",
ValidateErrors.builder().errors(e.getBindingResult()).build());
}
/**
* 参数验证异常
*
* @param e 异常
* @return 异常信息
*/
@ResponseBody
@ExceptionHandler(value = WebExchangeBindException.class)
public Response webExchangeBindException(WebExchangeBindException e) {
return Response.failed(Response.FAILED, "参数验证异常",
ValidateErrors.builder().errors(e.getBindingResult()).build());
}
/**
* 参数绑定异常
*
* @param e 异常
* @return 异常信息
*/
@ResponseBody
@ExceptionHandler(value = BindException.class)
public Response bindException(BindException e) {
return Response.failed(Response.FAILED, "参数绑定异常",
ValidateErrors.builder().errors(e.getBindingResult()).build());
}
/**
* 方法参数验证异常
*
* @param e 异常
* @return 异常信息
*/
@ResponseBody
@ExceptionHandler(value = ConstraintViolationException.class)
public Response constraintViolationException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
Map<String, String> fieldErrors = new HashMap<>(constraintViolations.size());
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
Path propertyPath = constraintViolation.getPropertyPath();
Iterator<Path.Node> iterator = propertyPath.iterator();
Path.Node node = null;
while (iterator.hasNext()) {
node = iterator.next();
}
if (node != null) {
fieldErrors.put(node.getName(), constraintViolation.getMessage());
}
}
return Response.failed(Response.FAILED, "方法参数验证异常",
ValidateErrors.builder().fieldErrors(fieldErrors).build());
}
/**
* 拦截异常
*
* @param e 异常
* @return 异常信息
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Response exception(Exception e) {
log.error(e.getMessage(), e);
return Response.failed(Response.FAILED, e.getMessage());
}
}