1. import com.alibaba.fastjson.JSON;
    2. import com.fasterxml.jackson.databind.JsonMappingException;
    3. import lombok.Data;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.springframework.beans.ConversionNotSupportedException;
    6. import org.springframework.beans.TypeMismatchException;
    7. import org.springframework.http.converter.HttpMessageNotReadableException;
    8. import org.springframework.http.converter.HttpMessageNotWritableException;
    9. import org.springframework.util.CollectionUtils;
    10. import org.springframework.validation.ObjectError;
    11. import org.springframework.web.HttpMediaTypeNotAcceptableException;
    12. import org.springframework.web.HttpRequestMethodNotSupportedException;
    13. import org.springframework.web.bind.MethodArgumentNotValidException;
    14. import org.springframework.web.bind.MissingServletRequestParameterException;
    15. import org.springframework.web.bind.annotation.ControllerAdvice;
    16. import org.springframework.web.bind.annotation.ExceptionHandler;
    17. import org.springframework.web.bind.annotation.ResponseBody;
    18. import javax.servlet.ServletException;
    19. import javax.validation.ConstraintViolation;
    20. import javax.validation.ConstraintViolationException;
    21. import java.io.IOException;
    22. import java.net.ConnectException;
    23. import java.util.List;
    24. import java.util.Set;
    25. @ControllerAdvice
    26. @Slf4j
    27. public class GlobalExceptionHandler {
    28. //运行时异常
    29. @ExceptionHandler(RuntimeException.class)
    30. @ResponseBody
    31. public RestResponse runtimeExceptionHandler(RuntimeException runtimeException) {
    32. ResultDO<String> result = result(MyException.RUNTIME_EXCEPTION.getCode(), MyException.RUNTIME_EXCEPTION.getMsg(), runtimeException);
    33. return RestResponse.buildError(JSON.toJSONString(result),MyException.RUNTIME_EXCEPTION.getMsg());
    34. }
    35. //空指针异常
    36. @ExceptionHandler(NullPointerException.class)
    37. @ResponseBody
    38. public RestResponse nullPointerExceptionHandler(NullPointerException ex) {
    39. ResultDO<String> result = result(MyException.NULL_POINTER_EXCEPTION.getCode(), MyException.NULL_POINTER_EXCEPTION.getMsg(), ex);
    40. return RestResponse.buildError(JSON.toJSONString(result),MyException.NULL_POINTER_EXCEPTION.getMsg());
    41. }
    42. //类型转换异常
    43. @ExceptionHandler(ClassCastException.class)
    44. @ResponseBody
    45. public RestResponse classCastExceptionHandler(ClassCastException ex) {
    46. ResultDO<String> result = result(MyException.CLASS_CAST_EXCEPTION.getCode(), MyException.CLASS_CAST_EXCEPTION.getMsg(), ex);
    47. return RestResponse.buildError(JSON.toJSONString(result),MyException.CLASS_CAST_EXCEPTION.getMsg());
    48. }
    49. //IO异常
    50. @ExceptionHandler(IOException.class)
    51. @ResponseBody
    52. public RestResponse iOExceptionHandler(IOException ex) {
    53. ResultDO<String> result = result(MyException.IO_EXCEPTION.getCode(), MyException.IO_EXCEPTION.getMsg(), ex);
    54. return RestResponse.buildError(JSON.toJSONString(result),MyException.IO_EXCEPTION.getMsg());
    55. }
    56. //未知方法异常
    57. @ExceptionHandler(NoSuchMethodException.class)
    58. @ResponseBody
    59. public RestResponse noSuchMethodExceptionHandler(NoSuchMethodException ex) {
    60. ResultDO<String> result = result(MyException.NO_SUCH_METHOD_EXCEPTION.getCode(), MyException.NO_SUCH_METHOD_EXCEPTION.getMsg(), ex);
    61. return RestResponse.buildError(JSON.toJSONString(result),MyException.NO_SUCH_METHOD_EXCEPTION.getMsg());
    62. }
    63. //数组越界异常
    64. @ExceptionHandler(IndexOutOfBoundsException.class)
    65. @ResponseBody
    66. public RestResponse indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
    67. ResultDO<String> result = result(MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getCode(), MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMsg(), ex);
    68. return RestResponse.buildError(JSON.toJSONString(result),MyException.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMsg());
    69. }
    70. //网络异常
    71. @ExceptionHandler(ConnectException.class)
    72. @ResponseBody
    73. public RestResponse connectException(ConnectException ex) {
    74. ResultDO<String> result = result(MyException.CONNECT_EXCEPTION.getCode(), MyException.CONNECT_EXCEPTION.getMsg(), ex);
    75. return RestResponse.buildError(JSON.toJSONString(result),MyException.CONNECT_EXCEPTION.getMsg());
    76. }
    77. //jackJson反序列化异常 400错误
    78. @ExceptionHandler({HttpMessageNotReadableException.class})
    79. @ResponseBody
    80. public RestResponse requestNotReadable(HttpMessageNotReadableException ex) {
    81. ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
    82. return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
    83. }
    84. //请求类型不匹配,400错误
    85. @ExceptionHandler({TypeMismatchException.class})
    86. @ResponseBody
    87. public RestResponse requestTypeMismatch(TypeMismatchException ex) {
    88. ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
    89. return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
    90. }
    91. //参数解析异常 400错误
    92. @ExceptionHandler({MissingServletRequestParameterException.class})
    93. @ResponseBody
    94. public RestResponse requestMissingServletRequest(MissingServletRequestParameterException ex) {
    95. ResultDO<String> result = result(MyException.BAD_REQUEST.getCode(), MyException.BAD_REQUEST.getMsg(), ex);
    96. return RestResponse.buildError(JSON.toJSONString(result),MyException.BAD_REQUEST.getMsg());
    97. }
    98. @ExceptionHandler({ ServletException.class })
    99. @ResponseBody
    100. public RestResponse http404(ServletException ex) {
    101. ResultDO<String> result = result(MyException.NOT_FOUND_REQUEST.getCode(), MyException.NOT_FOUND_REQUEST.getMsg(), ex);
    102. return RestResponse.buildError(JSON.toJSONString(result),MyException.NOT_FOUND_REQUEST.getMsg());
    103. }
    104. //请求方式不支持 405错误
    105. @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    106. @ResponseBody
    107. public RestResponse request405(HttpRequestMethodNotSupportedException ex) {
    108. ResultDO<String> result = result(MyException.METHOD_NOT_ALLOWED.getCode(), MyException.METHOD_NOT_ALLOWED.getMsg(), ex);
    109. return RestResponse.buildError(JSON.toJSONString(result),MyException.METHOD_NOT_ALLOWED.getMsg());
    110. }
    111. //媒体类型不支持 406错误
    112. @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    113. @ResponseBody
    114. public RestResponse request406(HttpMediaTypeNotAcceptableException ex) {
    115. ResultDO<String> result = result(MyException.NOT_ACCEPTABLE.getCode(), MyException.NOT_ACCEPTABLE.getMsg(), ex);
    116. return RestResponse.buildError(JSON.toJSONString(result),MyException.NOT_ACCEPTABLE.getMsg());
    117. }
    118. //转换异常 500错误
    119. @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    120. @ResponseBody
    121. public RestResponse server500(RuntimeException runtimeException) {
    122. ResultDO<String> result = result(MyException.INTERNAL_SERVER_ERROR.getCode(), MyException.INTERNAL_SERVER_ERROR.getMsg(), runtimeException);
    123. return RestResponse.buildError(JSON.toJSONString(result),MyException.INTERNAL_SERVER_ERROR.getMsg());
    124. }
    125. //json映射映射异常
    126. @ExceptionHandler({JsonMappingException.class})
    127. @ResponseBody
    128. public RestResponse jsonMappingException(JsonMappingException jsonMappingException) {
    129. ResultDO<String> result = result(MyException.ERROR_FORMAT_PARAMETER.getCode(), MyException.ERROR_FORMAT_PARAMETER.getMsg(), jsonMappingException);
    130. return RestResponse.buildError(JSON.toJSONString(result),MyException.INTERNAL_SERVER_ERROR.getMsg());
    131. }
    132. /**
    133. * 结果集
    134. * @param errCode
    135. * @param errMsg
    136. * @param e
    137. * @return
    138. */
    139. private ResultDO<String> result(Integer errCode, String errMsg, Exception e){
    140. ResultDO<String> resultDO = new ResultDO<String>();
    141. resultDO.setErrCode(errCode);
    142. resultDO.setErrMsg(errMsg+","+MyExceptionUtil.getMyStackTrace(e.getStackTrace()));
    143. logException(e);
    144. return resultDO;
    145. }
    146. /**
    147. * 用来处理bean validation异常
    148. *
    149. * @param ex
    150. * @return
    151. */
    152. @ExceptionHandler(ConstraintViolationException.class)
    153. @ResponseBody
    154. public RestResponse resolveConstraintViolationException(ConstraintViolationException ex) {
    155. Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
    156. if (!CollectionUtils.isEmpty(constraintViolations)) {
    157. return RestResponse.buildError(constraintViolations.iterator().next().getMessage(),"40010");
    158. }
    159. return RestResponse.buildError(ex.getMessage(),"40010");
    160. }
    161. @ExceptionHandler(MethodArgumentNotValidException.class)
    162. @ResponseBody
    163. public RestResponse resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
    164. List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
    165. if (!CollectionUtils.isEmpty(objectErrors)) {
    166. String defaultMessage = objectErrors.get(0).getDefaultMessage();
    167. return RestResponse.buildError(defaultMessage,"40010");
    168. }
    169. return RestResponse.buildError(ex.getMessage(),"40010");
    170. }
    171. /**
    172. * 异常记录
    173. * @param e
    174. */
    175. private void logException(Exception e){
    176. log.error(e.getMessage(), e);
    177. DingTalkUtil.send("异常描述:\n"+"localizedMessage: \n"+e.getLocalizedMessage()+" \n message: \n"+e.getMessage()+"\n异常堆栈:\n"+MyExceptionUtil.getMyStackTrace(e.getStackTrace()));
    178. }
    179. @Data
    180. private class ResultDO<T> {
    181. private Integer ErrCode;
    182. private String ErrMsg;
    183. }
    184. }