|
@@ -12,6 +12,7 @@ import javax.validation.ConstraintViolationException;
|
|
|
|
|
|
import org.apache.ibatis.exceptions.PersistenceException;
|
|
|
import org.mybatis.spring.MyBatisSystemException;
|
|
|
+import org.springframework.dao.DataAccessException;
|
|
|
import org.springframework.dao.DataIntegrityViolationException;
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
@@ -35,114 +36,82 @@ import com.gihon.component.response.Response;
|
|
|
import com.gihon.component.response.ResponseStatus;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
/**
|
|
|
* 基本的全局异常处理器
|
|
|
+ *
|
|
|
* @author baihe
|
|
|
*
|
|
|
*/
|
|
|
@Slf4j
|
|
|
@ControllerAdvice(annotations = {RestController.class, Controller.class})
|
|
|
@ResponseBody
|
|
|
-@SuppressWarnings({ "unused", "rawtypes" })
|
|
|
+@SuppressWarnings({"unused", "rawtypes"})
|
|
|
public class CommonExceptionController {
|
|
|
-
|
|
|
- //通过Handler获取到Controller的返回值类型
|
|
|
- private ResponseEntity<Response> createResponse(HandlerMethod handler,ResponseStatus status,String message) {
|
|
|
- Response r = Response.error(status,message);
|
|
|
- return new ResponseEntity<>(r, HttpStatus.OK);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ExceptionHandler(BaseException.class)
|
|
|
- public Response handleBaseException(HttpServletRequest req,HandlerMethod handler,BaseException e){
|
|
|
- log.error("["+e.getMessage()+"]",e);
|
|
|
- return Response.error(e.getStatus(),e.getMessage());
|
|
|
- }
|
|
|
-
|
|
|
- @ExceptionHandler(Throwable.class)
|
|
|
- public Response handleThrowable(HttpServletRequest req,HandlerMethod handler,Throwable e){
|
|
|
- log.error("["+e.getMessage()+"]",e);
|
|
|
- return Response.error(ResponseStatus.ERROR,ResponseStatus.ERROR.getDesc());
|
|
|
- }
|
|
|
- @ExceptionHandler(AccessDeniedException.class)
|
|
|
- public Response handleThrowable(HttpServletRequest req,HandlerMethod handler,AccessDeniedException e){
|
|
|
- log.error("["+e.getMessage()+"]",e);
|
|
|
- return Response.error(ResponseStatus.FORBIDDEN,ResponseStatus.FORBIDDEN.getDesc());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 在controller中使用 @Valid or @Validator 抛出的异常
|
|
|
- * @param req
|
|
|
- * @param e
|
|
|
- * @return
|
|
|
- */
|
|
|
- @ExceptionHandler(MethodArgumentNotValidException.class)
|
|
|
- public Response MethodArgumentNotValidExceptionHandler(HttpServletRequest req,HandlerMethod handler,MethodArgumentNotValidException e) {
|
|
|
- log.error("[MethodArgumentNotValidException] ",e);
|
|
|
- StringBuilder message = new StringBuilder();
|
|
|
- for (ObjectError error : e.getBindingResult().getAllErrors()) {
|
|
|
- message.append(error.getDefaultMessage()).append("\n");
|
|
|
- }
|
|
|
- return Response.error(ResponseStatus.VALID_ERROR,message.toString());
|
|
|
+
|
|
|
+ // 通过Handler获取到Controller的返回值类型
|
|
|
+ private ResponseEntity<Response> createResponse(HandlerMethod handler, ResponseStatus status, String message) {
|
|
|
+ Response r = Response.error(status, message);
|
|
|
+ return new ResponseEntity<>(r, HttpStatus.OK);
|
|
|
}
|
|
|
- @ExceptionHandler(HttpMessageNotReadableException.class)
|
|
|
- public Response httpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request) {
|
|
|
- log.error("[HttpMessageNotReadableException] ",e);
|
|
|
- String message = e.getMessage();
|
|
|
- String msg="参数解析失败";
|
|
|
- if (StringUtils.substringMatch(message, 0, "Could not read document:")) {
|
|
|
- int index = message.indexOf("Could not read document:");
|
|
|
- int index2 = message.indexOf(" at ");
|
|
|
- msg = String.format("无法正确的解析json类型的参数:%s", message.substring(index+24, index2));
|
|
|
+
|
|
|
+ @ExceptionHandler(Throwable.class)
|
|
|
+ public Response handleThrowable(HttpServletRequest req, HandlerMethod handler, Throwable e) {
|
|
|
+ log.error("[" + e.getMessage() + "]", e);
|
|
|
+ return Response.error(ResponseStatus.ERROR, ResponseStatus.ERROR.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @ExceptionHandler(BaseException.class)
|
|
|
+ public Response handleBaseException(HttpServletRequest req, HandlerMethod handler, BaseException e) {
|
|
|
+ log.error("[" + e.getMessage() + "]", e);
|
|
|
+ return Response.error(e.getStatus(), e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * JSON方式 @Valid or @Validated 抛出的异常
|
|
|
+ *
|
|
|
+ * @param req
|
|
|
+ * @param e
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ExceptionHandler(MethodArgumentNotValidException.class)
|
|
|
+ public Response methodArgumentNotValidExceptionHandler(HttpServletRequest req, HandlerMethod handler,
|
|
|
+ MethodArgumentNotValidException e) {
|
|
|
+ log.error("[MethodArgumentNotValidException] ", e);
|
|
|
+ StringBuilder message = new StringBuilder();
|
|
|
+ for (ObjectError error : e.getBindingResult().getAllErrors()) {
|
|
|
+ message.append(error.getDefaultMessage()).append("\n");
|
|
|
}
|
|
|
- return Response.error(ResponseStatus.PARAM_ERROR,msg);
|
|
|
+ return Response.error(ResponseStatus.VALID_ERROR, message.toString());
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * form data 方式接受参数 @Valid
|
|
|
+ *
|
|
|
+ * @param e
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
@ExceptionHandler(BindException.class)
|
|
|
public Response bindException(BindException e, HttpServletRequest request) {
|
|
|
- log.error("[BindException] ",e);
|
|
|
+ log.error("[BindException] ", e);
|
|
|
try {
|
|
|
String msgs = e.getBindingResult().getFieldError().getDefaultMessage();
|
|
|
- if (!StringUtils.isEmpty(msgs)) {
|
|
|
+ if (StringUtils.hasText(msgs)) {
|
|
|
return Response.error(ResponseStatus.PARAM_ERROR, msgs);
|
|
|
}
|
|
|
} catch (Exception ee) {
|
|
|
}
|
|
|
StringBuilder msg = new StringBuilder();
|
|
|
List<FieldError> fieldErrors = e.getFieldErrors();
|
|
|
- fieldErrors.forEach((oe) ->
|
|
|
- msg.append("参数:[").append(oe.getObjectName())
|
|
|
- .append(".").append(oe.getField())
|
|
|
- .append("]的传入值:[").append(oe.getRejectedValue()).append("]与预期的字段类型不匹配.")
|
|
|
- );
|
|
|
- return Response.error(ResponseStatus.PARAM_ERROR,msg.toString());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
|
|
- public Response methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
|
|
- log.error("[MethodArgumentTypeMismatchException] ",e);
|
|
|
- MethodArgumentTypeMismatchException eee = (MethodArgumentTypeMismatchException) e;
|
|
|
- StringBuilder msg = new StringBuilder("参数:[").append(eee.getName())
|
|
|
- .append("]的传入值:[").append(eee.getValue())
|
|
|
- .append("]与预期的字段类型:[").append(eee.getRequiredType().getName()).append("]不匹配");
|
|
|
- return Response.error(ResponseStatus.PARAM_ERROR,msg.toString());
|
|
|
+ fieldErrors.forEach((oe) -> msg.append("参数:[").append(oe.getObjectName()).append(".").append(oe.getField())
|
|
|
+ .append("]的传入值:[").append(oe.getRejectedValue()).append("]与预期的字段类型不匹配."));
|
|
|
+ return Response.error(ResponseStatus.PARAM_ERROR, msg.toString());
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- @ExceptionHandler(MissingServletRequestParameterException.class)
|
|
|
- public Response missingServletRequestParameterException(MissingServletRequestParameterException e, HttpServletRequest request) {
|
|
|
- log.error("[MissingServletRequestParameterException]", e);
|
|
|
- StringBuilder msg = new StringBuilder();
|
|
|
- msg.append("缺少必须的[").append(e.getParameterType()).append("]类型的参数[").append(e.getParameterName()).append("]");
|
|
|
- return Response.error(ResponseStatus.PARAM_ERROR,msg.toString());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
- * jsr 规范中的验证异常
|
|
|
- *
|
|
|
+ * jsr 规范中的验证异常 单个参数校验异常抛出ConstraintViolationException
|
|
|
+ *
|
|
|
* @param e
|
|
|
* @return
|
|
|
*/
|
|
@@ -150,21 +119,61 @@ public class CommonExceptionController {
|
|
|
public Response constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
|
|
|
log.error("[ConstraintViolationException]", e);
|
|
|
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
|
|
|
- String message = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
|
|
|
- return Response.error(ResponseStatus.VALID_ERROR,message);
|
|
|
+ String message = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("\n"));
|
|
|
+ return Response.error(ResponseStatus.VALID_ERROR, message);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 参数读取失败
|
|
|
+ *
|
|
|
+ * @param e
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ExceptionHandler(HttpMessageNotReadableException.class)
|
|
|
+ public Response httpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request) {
|
|
|
+ log.error("[HttpMessageNotReadableException] ", e);
|
|
|
+ String message = e.getMessage();
|
|
|
+ String msg = "参数解析失败";
|
|
|
+ if (StringUtils.substringMatch(message, 0, "Could not read document:")) {
|
|
|
+ int index = message.indexOf("Could not read document:");
|
|
|
+ int index2 = message.indexOf(" at ");
|
|
|
+ msg = String.format("无法正确的解析json类型的参数:%s", message.substring(index + 24, index2));
|
|
|
+ }
|
|
|
+ return Response.error(ResponseStatus.PARAM_ERROR, msg);
|
|
|
+ }
|
|
|
|
|
|
- @ExceptionHandler(PersistenceException.class)
|
|
|
- public Response persistenceException(PersistenceException e, HttpServletRequest request) {
|
|
|
- log.error("[PersistenceException]", e);
|
|
|
- return Response.error(ResponseStatus.SQL_ERROR);
|
|
|
+ /**
|
|
|
+ * 参数类型不正确不能解析
|
|
|
+ *
|
|
|
+ * @param e
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
|
|
+ public Response methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e,
|
|
|
+ HttpServletRequest request) {
|
|
|
+ log.error("[MethodArgumentTypeMismatchException] ", e);
|
|
|
+ MethodArgumentTypeMismatchException eee = (MethodArgumentTypeMismatchException)e;
|
|
|
+ StringBuilder msg = new StringBuilder("参数:[").append(eee.getName()).append("]的传入值:[").append(eee.getValue())
|
|
|
+ .append("]与预期的字段类型:[").append(eee.getRequiredType().getName()).append("]不匹配");
|
|
|
+ return Response.error(ResponseStatus.PARAM_ERROR, msg.toString());
|
|
|
}
|
|
|
|
|
|
- @ExceptionHandler(MyBatisSystemException.class)
|
|
|
- public Response myBatisSystemException(MyBatisSystemException e, HttpServletRequest request) {
|
|
|
- log.error("[PersistenceException]", e);
|
|
|
- return Response.error(ResponseStatus.SQL_ERROR);
|
|
|
+ /**
|
|
|
+ * 缺少必须的url参数 @RequestParam 注解
|
|
|
+ *
|
|
|
+ * @param e
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ExceptionHandler(MissingServletRequestParameterException.class)
|
|
|
+ public Response missingServletRequestParameterException(MissingServletRequestParameterException e,
|
|
|
+ HttpServletRequest request) {
|
|
|
+ log.error("[MissingServletRequestParameterException]", e);
|
|
|
+ StringBuilder msg = new StringBuilder();
|
|
|
+ msg.append("缺少必须的[").append(e.getParameterType()).append("]类型的参数[").append(e.getParameterName()).append("]");
|
|
|
+ return Response.error(ResponseStatus.PARAM_ERROR, msg.toString());
|
|
|
}
|
|
|
|
|
|
@ExceptionHandler(SQLException.class)
|
|
@@ -173,8 +182,8 @@ public class CommonExceptionController {
|
|
|
return Response.error(ResponseStatus.SQL_ERROR);
|
|
|
}
|
|
|
|
|
|
- @ExceptionHandler(DataIntegrityViolationException.class)
|
|
|
- public Response dataIntegrityViolationException(DataIntegrityViolationException e, HttpServletRequest request) {
|
|
|
+ @ExceptionHandler(DataAccessException.class)
|
|
|
+ public Response dataIntegrityViolationException(DataAccessException e, HttpServletRequest request) {
|
|
|
log.error("[DataIntegrityViolationException]", e);
|
|
|
return Response.error(ResponseStatus.SQL_ERROR);
|
|
|
}
|