WANG 6 жил өмнө
parent
commit
691e4a6cf0

+ 62 - 0
src/main/java/cn/com/qmth/examcloud/web/enums/HttpServletRequestAttribute.java

@@ -0,0 +1,62 @@
+package cn.com.qmth.examcloud.web.enums;
+
+/**
+ * servlet请求属性
+ *
+ * @author WANGWEI
+ * @date 2019年3月21日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public enum HttpServletRequestAttribute {
+
+	/**
+	 * 请求映射
+	 */
+	$_MAPPING,
+
+	/**
+	 * API 信息
+	 */
+	$_API_INFO,
+
+	/**
+	 * 接入类型
+	 */
+	$_ACCESS_TYPE,
+
+	/**
+	 * http status恒为200
+	 */
+	$_ALWAYS_OK,
+
+	/**
+	 * 接入的管理员用户
+	 */
+	$_ACCESS_ADMIN_USER,
+
+	/**
+	 * 接入的分区用户
+	 */
+	$_ACCESS_PARTITION_USER,
+
+	/**
+	 * 接入的APP
+	 */
+	$_ACCESS_APP,
+
+	/**
+	 * 接入的企业
+	 */
+	$_ACCESS_ENTERPRISE,
+
+	/**
+	 * 自定义顺序锁
+	 */
+	$_CUSTOM_SEQUENCE_LOCK,
+
+	/**
+	 * 已鉴权(其他拦截器处理)
+	 */
+	$_AUTHORIZED_BY_OTHER_INTERCEPTOR
+
+}

+ 109 - 62
src/main/java/cn/com/qmth/examcloud/web/support/CustomExceptionHandler.java

@@ -1,16 +1,19 @@
 package cn.com.qmth.examcloud.web.support;
 package cn.com.qmth.examcloud.web.support;
 
 
-import java.util.HashSet;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
 
 
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.ObjectError;
+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.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -19,8 +22,7 @@ import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.util.JsonUtil;
 import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.commons.util.PropertiesUtil;
-import cn.com.qmth.examcloud.commons.util.RegExpUtil;
+import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
 
 
 /**
 /**
  * 类注释
  * 类注释
@@ -39,22 +41,6 @@ public class CustomExceptionHandler {
 	private static final ExamCloudLog INTERFACE_LOG = ExamCloudLogFactory
 	private static final ExamCloudLog INTERFACE_LOG = ExamCloudLogFactory
 			.getLog("INTERFACE_LOGGER");
 			.getLog("INTERFACE_LOGGER");
 
 
-	private static ExamCloudLog LOG = ExamCloudLogFactory.getLog(CustomExceptionHandler.class);
-
-	/**
-	 * 不输出堆栈的状态码
-	 */
-	private static Set<String> nonStackTraceStatusCodes = new HashSet<>();
-
-	static {
-		String str = PropertiesUtil.getString("$log.nonStackTraceStatusCodes");
-		if (StringUtils.isNotBlank(str)) {
-			List<String> list = RegExpUtil.findAll(str, "[\\w\\-]+");
-			CollectionUtils.addAll(nonStackTraceStatusCodes, list);
-			LOG.info("nonStackTraceStatusCodes: " + JsonUtil.toJson(nonStackTraceStatusCodes));
-		}
-	}
-
 	/**
 	/**
 	 * 异常处理
 	 * 异常处理
 	 *
 	 *
@@ -70,39 +56,96 @@ public class CustomExceptionHandler {
 		Throwable cause = e.getCause();
 		Throwable cause = e.getCause();
 		StatusResponse body = null;
 		StatusResponse body = null;
 
 
-		if (null != cause && cause instanceof StatusException) {
+		if (null == cause) {
+			body = new StatusResponse("500", "系统异常");
+			cause = e;
+		} else if (cause instanceof StatusException) {
 			StatusException se = (StatusException) cause;
 			StatusException se = (StatusException) cause;
 			body = new StatusResponse(se.getCode(), se.getDesc());
 			body = new StatusResponse(se.getCode(), se.getDesc());
-		} else if (null != cause && cause instanceof DataIntegrityViolationException) {
-			body = new StatusResponse(ResponseStatus.DATA_INTEGRITY_VIOLATION.getCode(),
-					ResponseStatus.DATA_INTEGRITY_VIOLATION.getDesc());
-		} else if (null != cause && cause instanceof IllegalStateException) {
-			IllegalStateException se = (IllegalStateException) cause;
-			body = new StatusResponse(ResponseStatus.FATAL_ERROR.getCode(), se.getMessage());
+		} else if (cause instanceof IllegalStateException) {
+			body = new StatusResponse("500", cause.getMessage());
+		} else if (cause instanceof javax.validation.ConstraintViolationException) {
+			javax.validation.ConstraintViolationException cvExcp = (ConstraintViolationException) cause;
+			Set<ConstraintViolation<?>> constraintViolations = cvExcp.getConstraintViolations();
+
+			StringBuffer errorMsg = new StringBuffer();
+			boolean isFirst = true;
+			for (ConstraintViolation<?> cv : constraintViolations) {
+				if (isFirst) {
+					errorMsg.append(cv.getMessage());
+					isFirst = false;
+				} else {
+					errorMsg.append("; ").append(cv.getMessage());
+				}
+			}
+			body = new StatusResponse("500", errorMsg.toString());
+		} else if (cause instanceof org.springframework.jdbc.CannotGetJdbcConnectionException) {
+			body = new StatusResponse("500", "网络拥堵,请稍后重试");
 		} else {
 		} else {
-			body = new StatusResponse(ResponseStatus.FATAL_ERROR.getCode(),
-					ResponseStatus.FATAL_ERROR.getDesc());
+			body = new StatusResponse("500", "系统异常");
 			cause = e;
 			cause = e;
 		}
 		}
 
 
-		boolean alwaysOK = alwaysOK(request);
-		if (alwaysOK) {
-			INTERFACE_LOG.error("[HTTP-RESP]. StatusCode=" + HttpStatus.OK);
-			if (nonStackTraceStatusCodes.contains(body.getCode())) {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body));
-			} else {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), cause);
-			}
-			return new ResponseEntity<StatusResponse>(body, HttpStatus.OK);
-		} else {
-			INTERFACE_LOG.error("[HTTP-RESP]. StatusCode=" + HttpStatus.INTERNAL_SERVER_ERROR);
-			if (nonStackTraceStatusCodes.contains(body.getCode())) {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body));
+		return asResult(cause, body, request);
+	}
+
+	/**
+	 * 异常处理
+	 *
+	 * @author WANGWEI
+	 * @param e
+	 * @param request
+	 * @return
+	 */
+	@ExceptionHandler(MethodArgumentNotValidException.class)
+	public ResponseEntity<StatusResponse> handleException(MethodArgumentNotValidException e,
+			HttpServletRequest request) {
+		BindingResult result = e.getBindingResult();
+		List<ObjectError> allErrors = result.getAllErrors();
+		StringBuffer errorMsg = new StringBuffer();
+		boolean isFirst = true;
+		for (ObjectError err : allErrors) {
+			if (isFirst) {
+				errorMsg.append(err.getDefaultMessage());
+				isFirst = false;
 			} else {
 			} else {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), cause);
+				errorMsg.append("; ").append(err.getDefaultMessage());
 			}
 			}
-			return new ResponseEntity<StatusResponse>(body, HttpStatus.INTERNAL_SERVER_ERROR);
 		}
 		}
+		StatusResponse body = new StatusResponse("500", errorMsg.toString());
+		return asResult(e, body, request);
+	}
+
+	/**
+	 * 异常处理
+	 *
+	 * @author WANGWEI
+	 * @param e
+	 * @param request
+	 * @return
+	 */
+	@ExceptionHandler(MissingServletRequestParameterException.class)
+	public ResponseEntity<StatusResponse> handleException(MissingServletRequestParameterException e,
+			HttpServletRequest request) {
+
+		StatusResponse body = new StatusResponse("500", e.getMessage());
+		return asResult(e, body, request);
+	}
+
+	/**
+	 * 异常处理
+	 *
+	 * @author WANGWEI
+	 * @param e
+	 * @param request
+	 * @return
+	 */
+	@ExceptionHandler(HttpMessageNotReadableException.class)
+	public ResponseEntity<StatusResponse> handleException(HttpMessageNotReadableException e,
+			HttpServletRequest request) {
+
+		StatusResponse body = new StatusResponse("500", "Required request body is missing");
+		return asResult(e, body, request);
 	}
 	}
 
 
 	/**
 	/**
@@ -116,26 +159,30 @@ public class CustomExceptionHandler {
 	@ExceptionHandler(Exception.class)
 	@ExceptionHandler(Exception.class)
 	public ResponseEntity<StatusResponse> handleException(Exception e, HttpServletRequest request) {
 	public ResponseEntity<StatusResponse> handleException(Exception e, HttpServletRequest request) {
 
 
-		StatusResponse body = new StatusResponse(
-				cn.com.qmth.examcloud.web.support.ResponseStatus.FATAL_ERROR.getCode(),
-				cn.com.qmth.examcloud.web.support.ResponseStatus.FATAL_ERROR.getDesc());
+		StatusResponse body = new StatusResponse("500", "致命错误");
+
+		return asResult(e, body, request);
+	}
 
 
+	/**
+	 * 构建响应结果
+	 *
+	 * @author WANGWEI
+	 * @param t
+	 * @param body
+	 * @param request
+	 * @return
+	 */
+	private ResponseEntity<StatusResponse> asResult(Throwable t, StatusResponse body,
+			HttpServletRequest request) {
 		boolean alwaysOK = alwaysOK(request);
 		boolean alwaysOK = alwaysOK(request);
 		if (alwaysOK) {
 		if (alwaysOK) {
-			INTERFACE_LOG.info("[HTTP-RESP]. StatusCode=" + HttpStatus.OK);
-			if (nonStackTraceStatusCodes.contains(body.getCode())) {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body));
-			} else {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), e);
-			}
+			INTERFACE_LOG.error("[HTTP-RESP]. status=" + HttpStatus.OK.value());
+			INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), t);
 			return new ResponseEntity<StatusResponse>(body, HttpStatus.OK);
 			return new ResponseEntity<StatusResponse>(body, HttpStatus.OK);
 		} else {
 		} else {
-			INTERFACE_LOG.info("[HTTP-RESP]. StatusCode=" + HttpStatus.INTERNAL_SERVER_ERROR);
-			if (nonStackTraceStatusCodes.contains(body.getCode())) {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body));
-			} else {
-				INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), e);
-			}
+			INTERFACE_LOG.error("[HTTP-RESP]. status=" + HttpStatus.INTERNAL_SERVER_ERROR.value());
+			INTERFACE_LOG.error("[HTTP-RESP]. response=" + JsonUtil.toJson(body), t);
 			return new ResponseEntity<StatusResponse>(body, HttpStatus.INTERNAL_SERVER_ERROR);
 			return new ResponseEntity<StatusResponse>(body, HttpStatus.INTERNAL_SERVER_ERROR);
 		}
 		}
 	}
 	}
@@ -149,7 +196,7 @@ public class CustomExceptionHandler {
 	 */
 	 */
 	private boolean alwaysOK(HttpServletRequest request) {
 	private boolean alwaysOK(HttpServletRequest request) {
 		boolean alwaysOK = false;
 		boolean alwaysOK = false;
-		Object attribute = request.getAttribute("$ALWAYS_OK");
+		Object attribute = request.getAttribute(HttpServletRequestAttribute.$_ALWAYS_OK.name());
 		if (null != attribute) {
 		if (null != attribute) {
 			try {
 			try {
 				alwaysOK = (boolean) attribute;
 				alwaysOK = (boolean) attribute;