GlobalExceptionResolver:
package com.cloud.web;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.cloud.exception.EyasException;
import com.cloud.exception.SfException;
import com.cloud.vo.SfResponseVO;
import com.google.common.collect.Maps;
import com.honghu.cloud.common.code.ResponseCode;
import com.honghu.cloud.common.code.ResponseVO;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
import java.util.Map;
/**
* 全局异常处理
* create by wangxs
* http://www.mkyong.com/spring-mvc/spring-mvc-exceptionhandler-example/
*/
@RestControllerAdvice
public class GlobalExceptionResolver {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionResolver.class);
/**
* 一般业务异常,不打印堆栈信息
* @param e
* @param request
* @return
*/
@ExceptionHandler(EyasException.class)
public ResponseVO handleResultException(EyasException e, HttpServletRequest request) {
//业务异常,不打印堆栈信息
logger.error("全局异常处理【EyasException】:errorCode={},message={}",e.getErrorCode(),e.getMessage());
return new ResponseVO(e.getErrorCode(),e.getMessage(),null);
}
/**
* 请求参数类型转换异常(满足Cause是InvalidFormatException异常类型的条件),不需要打印堆栈信息
* <p>{@link HttpMessageNotReadableException} && {@link InvalidFormatException}</p>
* @param e
* @param request
* @return
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseVO handleResultException(HttpMessageNotReadableException e, HttpServletRequest request) {
if(e.getCause() instanceof InvalidFormatException){
//参数类型转换失败,不需要打印堆栈信息
logger.error("全局异常处理【参数类型错误】:{}",e.getMessage());
return new ResponseVO(ResponseCode.RESPONSE_CODE_PARAM_ERROR.getCode(),ResponseCode.RESPONSE_CODE_PARAM_ERROR.getMessage(),null);
}else{
logger.error("全局异常处理【系统异常】",e);
return new ResponseVO(ResponseCode.RESPONSE_CODE_SYSTEM_ERROR.getCode(),ResponseCode.RESPONSE_CODE_SYSTEM_ERROR.getMessage(),null);
}
}
/**
* hibernate注解字段校验异常
* @param e
* @param request
* @return
*/
@ExceptionHandler(BindException.class)
public ResponseVO handleResultException(BindException e, HttpServletRequest request) {
//注解校验失败,不需要打印堆栈信息
logger.error("全局异常处理【参数校验错误】:{}",e.getMessage());
BindingResult bindingResult = e.getBindingResult();
Map<String,String> result = Maps.newHashMap();
if(bindingResult.hasErrors()){
List<FieldError> list = bindingResult.getFieldErrors();
for (FieldError fieldError : list) {
result.put(fieldError.getField(),fieldError.getDefaultMessage());
}
}
return new ResponseVO (ResponseCode.RESPONSE_CODE_PARAM_ERROR.getCode(),result.toString(),null);
}
/**
* hibernate注解字段校验异常
* @param e
* @param request
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseVO handleResultException(MethodArgumentNotValidException e, HttpServletRequest request) {
//注解校验失败,不需要打印堆栈信息
logger.error("全局异常处理【参数校验错误】:{}",e.getMessage());
BindingResult bindingResult = e.getBindingResult();
String errorMsg = "无错误消息";
if(bindingResult.hasErrors()){
for(FieldError error: bindingResult.getFieldErrors()){
//1、先打印出所有的校验错误字段信息
logger.error("参数校验错误:obj={}, field={}, reject={}, message={}",error.getObjectName()
,error.getField(),error.getRejectedValue(),error.getDefaultMessage());
//2、以最后一个参数错误信息做为异常抛出
errorMsg = error.getDefaultMessage();
}
}
return new ResponseVO(ResponseCode.RESPONSE_CODE_PARAM_ERROR.getCode(),errorMsg,null);
}
/**
* 系统异常,打印错误堆栈
* @param e
* @param request
* @return
*/
@ExceptionHandler(Exception.class)
public ResponseVO handleResultException(Exception e, HttpServletRequest request) {
logger.error("全局异常处理【系统异常】",e);
if(e instanceof MissingServletRequestParameterException){
return new ResponseVO (ResponseCode.RESPONSE_CODE_PARAM_ERROR.getCode(),e.getMessage(),null);
}else{
return new ResponseVO (ResponseCode.RESPONSE_CODE_SYSTEM_ERROR.getCode(),null);
}
}
@ExceptionHandler(SfException.class)
public SfResponseVO handleSfResultException(SfException e, HttpServletRequest request) {
//业务异常,不打印堆栈信息
logger.error("顺丰异常处理【SfException】:errorCode={},message={}",e.getErrorCode(),e.getMessage());
return new SfResponseVO(e.getErrorCode(),e.getMessage(),null);
}
/**
* 请求参数类型转换异常(满足Cause是InvalidFormatException异常类型的条件),不需要打印堆栈信息
* <p>{@link HttpMessageNotReadableException} && {@link InvalidFormatException}</p>
* @param e
* @param request
* @return
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseVO handleResultException(HttpMessageNotReadableException e, HttpServletRequest request) {
if(e.getCause() instanceof InvalidFormatException){
//参数类型转换失败,不需要打印堆栈信息
logger.error("全局异常处理【参数类型错误】:{}",e.getMessage());
return new ResponseVO(ResponseCode.RESPONSE_CODE_PARAM_ERROR.getCode(),ResponseCode.RESPONSE_CODE_PARAM_ERROR.getMessage(),null);
}else{
logger.error("全局异常处理【系统异常】",e);
return new ResponseVO(ResponseCode.RESPONSE_CODE_SYSTEM_ERROR.getCode(),ResponseCode.RESPONSE_CODE_SYSTEM_ERROR.getMessage(),null);
}
} */
}
GlobalResponseHandler:
package com.cloud.web;
import com.cloud.annotation.OutApi;
import com.honghu.cloud.common.code.ResponseCode;
import com.honghu.cloud.common.code.ResponseVO;
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.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* create by wangxs
*/
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
OutApi outApi = methodParameter.getMethod().getAnnotation(OutApi.class);
if(outApi != null){
return false;
}
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (body !=null && (body instanceof ResponseVO ||body.toString().contains("<"))){
return body;
}else {
return new ResponseVO(ResponseCode.RESPONSE_RETURN_CODE_SUCCESS.getCode(),ResponseCode.RESPONSE_RETURN_CODE_SUCCESS.getMessage(),body);
}
}
}