import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonMappingException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.net.ConnectException;
import java.util.List;
import java.util.Set;
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
//运行时异常
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public RestResponse runtimeExceptionHandler(RuntimeException runtimeException) {
ResultDO<String> result = result(MyException.RUNTIME_EXCEPTION.getCode(), MyException.RUNTIME_EXCEPTION.getMsg(), runtimeException);
return RestResponse.buildError(JSON.toJSONString(result),MyException.RUNTIME_EXCEPTION.getMsg());
}
//空指针异常
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public RestResponse nullPointerExceptionHandler(NullPointerException ex) {
ResultDO<String> result = result(MyException.NULL_POINTER_EXCEPTION.getCode(), MyException.NULL_POINTER_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.NULL_POINTER_EXCEPTION.getMsg());
}
//类型转换异常
@ExceptionHandler(ClassCastException.class)
@ResponseBody
public RestResponse classCastExceptionHandler(ClassCastException ex) {
ResultDO<String> result = result(MyException.CLASS_CAST_EXCEPTION.getCode(), MyException.CLASS_CAST_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.CLASS_CAST_EXCEPTION.getMsg());
}
//IO异常
@ExceptionHandler(IOException.class)
@ResponseBody
public RestResponse iOExceptionHandler(IOException ex) {
ResultDO<String> result = result(MyException.IO_EXCEPTION.getCode(), MyException.IO_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.IO_EXCEPTION.getMsg());
}
//未知方法异常
@ExceptionHandler(NoSuchMethodException.class)
@ResponseBody
public RestResponse noSuchMethodExceptionHandler(NoSuchMethodException ex) {
ResultDO<String> result = result(MyException.NO_SUCH_METHOD_EXCEPTION.getCode(), MyException.NO_SUCH_METHOD_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.NO_SUCH_METHOD_EXCEPTION.getMsg());
}
//数组越界异常
@ExceptionHandler(IndexOutOfBoundsException.class)
@ResponseBody
public RestResponse indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
ResultDO<String> result = result(MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getCode(), MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMsg());
}
//网络异常
@ExceptionHandler(ConnectException.class)
@ResponseBody
public RestResponse connectException(ConnectException ex) {
ResultDO<String> result = result(MyException.CONNECT_EXCEPTION.getCode(), MyException.CONNECT_EXCEPTION.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.CONNECT_EXCEPTION.getMsg());
}
//jackJson反序列化异常 400错误
@ExceptionHandler({HttpMessageNotReadableException.class})
@ResponseBody
public RestResponse requestNotReadable(HttpMessageNotReadableException ex) {
ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
}
//请求类型不匹配,400错误
@ExceptionHandler({TypeMismatchException.class})
@ResponseBody
public RestResponse requestTypeMismatch(TypeMismatchException ex) {
ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
}
//参数解析异常 400错误
@ExceptionHandler({MissingServletRequestParameterException.class})
@ResponseBody
public RestResponse requestMissingServletRequest(MissingServletRequestParameterException ex) {
ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
}
@ExceptionHandler({ ServletException.class })
@ResponseBody
public RestResponse http404(ServletException ex) {
ResultDO<String> result = result(MyException.NOT_FOUND_REQUEST.getCode(), MyException.NOT_FOUND_REQUEST.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.NOT_FOUND_REQUEST.getMsg());
}
//请求方式不支持 405错误
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
@ResponseBody
public RestResponse request405(HttpRequestMethodNotSupportedException ex) {
ResultDO<String> result = result(MyException.METHOD_NOT_ALLOWED.getCode(), MyException.METHOD_NOT_ALLOWED.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.METHOD_NOT_ALLOWED.getMsg());
}
//媒体类型不支持 406错误
@ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
@ResponseBody
public RestResponse request406(HttpMediaTypeNotAcceptableException ex) {
ResultDO<String> result = result(MyException.NOT_ACCEPTABLE.getCode(), MyException.NOT_ACCEPTABLE.getMsg(), ex);
return RestResponse.buildError(JSON.toJSONString(result),MyException.NOT_ACCEPTABLE.getMsg());
}
//转换异常 500错误
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
@ResponseBody
public RestResponse server500(RuntimeException runtimeException) {
ResultDO<String> result = result(MyException.INTERNAL_SERVER_ERROR.getCode(), MyException.INTERNAL_SERVER_ERROR.getMsg(), runtimeException);
return RestResponse.buildError(JSON.toJSONString(result),MyException.INTERNAL_SERVER_ERROR.getMsg());
}
//json映射映射异常
@ExceptionHandler({JsonMappingException.class})
@ResponseBody
public RestResponse jsonMappingException(JsonMappingException jsonMappingException) {
ResultDO<String> result = result(MyException.ERROR_FORMAT_PARAMETER.getCode(), MyException.ERROR_FORMAT_PARAMETER.getMsg(), jsonMappingException);
return RestResponse.buildError(JSON.toJSONString(result),MyException.INTERNAL_SERVER_ERROR.getMsg());
}
/**
* 结果集
* @param errCode
* @param errMsg
* @param e
* @return
*/
private ResultDO<String> result(Integer errCode, String errMsg, Exception e){
ResultDO<String> resultDO = new ResultDO<String>();
resultDO.setErrCode(errCode);
resultDO.setErrMsg(errMsg+","+MyExceptionUtil.getMyStackTrace(e.getStackTrace()));
logException(e);
return resultDO;
}
/**
* 用来处理bean validation异常
*
* @param ex
* @return
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public RestResponse resolveConstraintViolationException(ConstraintViolationException ex) {
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
if (!CollectionUtils.isEmpty(constraintViolations)) {
return RestResponse.buildError(constraintViolations.iterator().next().getMessage(),"40010");
}
return RestResponse.buildError(ex.getMessage(),"40010");
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public RestResponse resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
if (!CollectionUtils.isEmpty(objectErrors)) {
String defaultMessage = objectErrors.get(0).getDefaultMessage();
return RestResponse.buildError(defaultMessage,"40010");
}
return RestResponse.buildError(ex.getMessage(),"40010");
}
/**
* 异常记录
* @param e
*/
private void logException(Exception e){
log.error(e.getMessage(), e);
DingTalkUtil.send("异常描述:\n"+"localizedMessage: \n"+e.getLocalizedMessage()+" \n message: \n"+e.getMessage()+"\n异常堆栈:\n"+MyExceptionUtil.getMyStackTrace(e.getStackTrace()));
}
@Data
private class ResultDO<T> {
private Integer ErrCode;
private String ErrMsg;
}
}