前言
mvc应用开发,基于Json数据的restfull交互接口。所有的正常或者异常的数据返回,都需要定义固定的格式。比如,系统出现异常,也能返回统一的错误码+错误信息,而不是返回一堆乱码给接口调用者。
统一返回的业务实体定义
package com.argrace.platform.dal.dto;
import lombok.Data;
@Data
public class Result<T> {
public enum ResultCode {
SUCCESS(200, "成功"),
REQUEST_ERROR(400, "请求错误"),
REQUEST_AUTH_ERROR(401, "请求认证错误"),
REQUEST_SIGN_ERROR(402, "请求签名错误"),
REQUEST_FORBIDDEN(403, "请求被禁止"),
SERVICE_NOT_FOUND(404, "服务未找到"),
SERVICE_ERROR(500, "服务端错误"),
SQL_ERROR(501, "服务端SQL错误"),
CALL_REMOTE_API_ERROR(2000, "服务端调用API失败"),
REMOTE_API_ERROR(2001, "远程API失败"),
PARAMETERS_IS_EMPTY(2002, "参数为空"),
PARAMETERS_IS_ERROR(2002, "参数错误")
;
private int value;
private String message;
ResultCode(int value, String message) {
this.value = value;
this.message = message;
}
public int getValue() {
return value;
}
public String getMessage() {
return message;
}
public String getMsg() {
return message;
}
public static ResultCode parseValue(int value) {
ResultCode[] values = ResultCode.values();
for (ResultCode resultCode : values) {
if (resultCode.getValue() == value) {
return resultCode;
}
}
return null;
}
}
private int code = 200;
private String message;
private T data;
public Result() {
}
public Result(T data) {
this.code = ResultCode.SUCCESS.getValue();
this.message = ResultCode.SUCCESS.getMessage();
this.data = data;
}
public Result(int code, String message) {
this.code = code;
this.message = message;
}
public static Result ok() {
return new Result<>(null);
}
public static <T> Result<T> ok(T data) {
return new Result<>(data);
}
public static <T> Result<T> error(ResultCode resultCode) {
return new Result<>(resultCode.value, resultCode.message);
}
public static <T> Result<T> withErr(ResultCode resultCode, String msg) {
return new Result<T>(resultCode.value, msg);
}
public static <T> Result<T> withErr(ResultCode resultCode) {
return new Result<T>(resultCode.value, resultCode.getMessage());
}
public static <T> Result<T> error(ResultCode resultCode, String message) {
return new Result<>(resultCode.value, message);
}
public static <T> Result<T> error(int code, String message) {
return new Result<>(code, message);
}
public static boolean isOk(Result result) {
return ResultCode.SUCCESS.getValue() == result.code;
}
}
统一异常处理类GlobalExceptionHandler
package com.argrace.platform.interceptor;
import com.argrace.platform.dal.dto.Result;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
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;
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler({
ConstraintViolationException.class})
@ResponseBody
public <T> Result<T> resolveConstraintViolationException(ConstraintViolationException ex) {
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
String msg;
if (!CollectionUtils.isEmpty(constraintViolations)) {
StringBuilder msgBuilder = new StringBuilder();
Iterator var5 = constraintViolations.iterator();
while(var5.hasNext()) {
ConstraintViolation constraintViolation = (ConstraintViolation)var5.next();
msgBuilder.append(constraintViolation.getMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
msg = errorMessage;
} else {
msg = ex.getMessage();
}
this.logger.info("bean参数检验不通过:{}", msg);
return Result.withErr(Result.ResultCode.PARAMETERS_IS_ERROR, msg);
}
@ExceptionHandler({
MethodArgumentNotValidException.class})
@ResponseBody
public <T> Result<T> resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
String msg;
if (!CollectionUtils.isEmpty(objectErrors)) {
StringBuilder msgBuilder = new StringBuilder();
Iterator var5 = objectErrors.iterator();
while(var5.hasNext()) {
ObjectError objectError = (ObjectError)var5.next();
msgBuilder.append(objectError.getDefaultMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
msg = errorMessage;
} else {
msg = ex.getMessage();
}
this.logger.info("method参数检验不通过:{}", msg);
return Result.withErr(Result.ResultCode.PARAMETERS_IS_ERROR, msg);
}
@ExceptionHandler({
BindException.class})
@ResponseBody
public <T> Result<T> bindException(BindException ex) {
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
String msg;
if (!CollectionUtils.isEmpty(objectErrors)) {
StringBuilder msgBuilder = new StringBuilder();
Iterator var5 = objectErrors.iterator();
while(var5.hasNext()) {
ObjectError objectError = (ObjectError)var5.next();
msgBuilder.append(objectError.getDefaultMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
msg = errorMessage;
} else {
msg = ex.getMessage();
}
this.logger.info("BindException参数检验不通过:{}", msg);
return Result.withErr(Result.ResultCode.PARAMETERS_IS_ERROR, msg);
}
@ExceptionHandler({
SQLException.class})
@ResponseBody
public <T> Result<T> handlerSQLException(SQLException ex) {
this.logger.error("SQL异常:result={}", ex.getMessage());
return Result.withErr(Result.ResultCode.SERVICE_ERROR, ex.getMessage());
}
@ExceptionHandler({
HttpRequestMethodNotSupportedException.class})
@ResponseBody
public <T> Result<T> handlerHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
this.logger.error("HttpRequestMethodNotSupportedException:result=", ex);
return Result.withErr(Result.ResultCode.SERVICE_ERROR, ex.getMessage());
}
@ExceptionHandler({
RuntimeException.class})
@ResponseBody
public <T> Result<T> handlerRuntimeException(RuntimeException ex) {
this.logger.error("RuntimeException:result=", ex);
return Result.withErr(Result.ResultCode.SERVICE_ERROR, ex.getMessage());
}
@ExceptionHandler({
Exception.class})
@ResponseBody
public <T> Result<T> handlerException(Exception ex) {
this.logger.error("Exception异常:result=", ex);
return Result.withErr(Result.ResultCode.SERVICE_ERROR);
}
}