Browse Source

修改全局异常处理

杨杰 6 years ago
parent
commit
d18753064b

+ 0 - 62
src/main/java/com/llisoft/sms/config/ErrorConfig.java

@@ -1,62 +0,0 @@
-package com.llisoft.sms.config;
-
-import java.util.Objects;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.web.servlet.error.ErrorController;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import com.llisoft.common.constant.CodeEnum;
-import com.llisoft.common.vo.ResponseVo;
-
-/**
- * 框架级异常处理, 覆盖默认/error
- * 根据错误信息返回具体的json结果
- * 模仿 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
- * @author YangJie [2018年12月27日]
- */
-@RestController
-public class ErrorConfig implements ErrorController {
-	
-	private Logger logger = LoggerFactory.getLogger(ErrorConfig.class);
-	
-
-	@RequestMapping("/error")
-	public ResponseVo<Object> error(HttpServletRequest request, HttpServletResponse response) {
-		response.setStatus(200); // 状态码全部200
-		Object statusCode = request.getAttribute("javax.servlet.error.status_code");
-		if(Objects.nonNull(statusCode) && statusCode instanceof Integer) {
-			int code = Integer.parseInt(statusCode.toString());
-			if(code == CodeEnum.C400.getCode()) {
-				logger.error("/error: {}", CodeEnum.C400.getMsg());
-				return ResponseVo.build(CodeEnum.C400);
-			}else if (code == CodeEnum.C401.getCode()) {
-				logger.error("/error: {}", CodeEnum.C401.getMsg());
-				return ResponseVo.build(CodeEnum.C401);
-			}else if (code == CodeEnum.C402.getCode()) {
-				logger.error("/error: {}", CodeEnum.C402.getMsg());
-				return ResponseVo.build(CodeEnum.C402);
-			}else if (code == CodeEnum.C403.getCode()) {
-				logger.error("/error: {}", CodeEnum.C403.getMsg());
-				return ResponseVo.build(CodeEnum.C403);
-			}else if (code == CodeEnum.C404.getCode()) {
-				logger.error("/error: {}", CodeEnum.C404.getMsg());
-				return ResponseVo.build(CodeEnum.C404);
-			}
-		}
-		logger.error("/error: {}", CodeEnum.C500.getMsg());
-		return ResponseVo.build(CodeEnum.C500);
-	}
-
-	
-	@Override
-	public String getErrorPath() {
-		return "/error";
-	}
-	
-}

+ 29 - 31
src/main/java/com/llisoft/sms/config/ExceptionConfig.java → src/main/java/com/llisoft/sms/config/ExceptionHandlerConfig.java

@@ -1,37 +1,31 @@
 package com.llisoft.sms.config;
 
-import java.nio.file.AccessDeniedException;
+import java.util.Objects;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.NoHandlerFoundException;
 
 import com.llisoft.common.constant.CodeEnum;
 import com.llisoft.common.exception.MtaException;
-import com.llisoft.common.vo.MailSendVo;
 import com.llisoft.common.vo.ResponseVo;
-import com.llisoft.sms.service.MailService;
 
 /**
  * 统一处理业务异常 controller
+ * 只能拦截到controller层的异常
+ * 如需拦截404等系统级异常,需要有如下配置
+ * spring.resources.addMappings: false #不为工程中的资源文件建立映射
+ * spring.mvc.throwExceptionIfNoHandlerFound: true #出现异常时直接抛出
  * @author YangJie [2018年12月26日]
  */
-@ControllerAdvice
-public class ExceptionConfig {
+@RestControllerAdvice
+public class ExceptionHandlerConfig {
 	
-	private Logger logger = LoggerFactory.getLogger(ExceptionConfig.class);
-	
-	@Value("${spring.application.name}")
-	private String application;
-	
-	@Autowired
-	private MailService mailService;
+	private Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
 	
 
     /**
@@ -40,7 +34,7 @@ public class ExceptionConfig {
      * @return
      */
     @ExceptionHandler(HttpMessageNotReadableException.class)
-    public @ResponseBody ResponseVo<String> exception(HttpMessageNotReadableException exception){
+    public ResponseVo<String> exception(HttpMessageNotReadableException exception){
     	logger.warn("入参异常: {}", exception.getMessage());
         return ResponseVo.build(CodeEnum.C400);
     }
@@ -51,31 +45,36 @@ public class ExceptionConfig {
      * @return
      */
     @ExceptionHandler(MethodArgumentNotValidException.class)
-    public @ResponseBody ResponseVo<String> exception(MethodArgumentNotValidException exception){
+    public ResponseVo<String> exception(MethodArgumentNotValidException exception){
     	logger.warn("入参异常: {}", exception.getMessage());
     	return ResponseVo.build(CodeEnum.C400.getCode(), exception.getBindingResult().getFieldError().getDefaultMessage());
     }
     
     /**
-     * 无权访问
+     * 业务异常
      * @param exception
      * @return
      */
-    @ExceptionHandler(AccessDeniedException.class)
-    public @ResponseBody ResponseVo<String> exception(AccessDeniedException exception){
-    	logger.warn("无权访问: {}", exception.getMessage());
-    	return ResponseVo.build(CodeEnum.C403);
+    @ExceptionHandler(MtaException.class)
+    public ResponseVo<String> exception(MtaException exception){
+    	CodeEnum codeEnum = exception.getCodeEnum();
+    	if (Objects.nonNull(codeEnum)) {
+    		return ResponseVo.build(codeEnum.getCode(), codeEnum.getMsg());
+		}
+    	logger.warn("业务异常: {}", exception.getMessage());
+    	return ResponseVo.build(CodeEnum.FAIL.getCode(), exception.getMessage());
     }
-	
+
+    
     /**
-     * 业务异常
+     * 地址异常
      * @param exception
      * @return
      */
-    @ExceptionHandler(MtaException.class)
-    public @ResponseBody ResponseVo<String> exception(MtaException exception){
-    	logger.warn("业务异常: {}", exception.getMessage());
-    	return ResponseVo.build(CodeEnum.FAIL.getCode(), exception.getMessage());
+    @ExceptionHandler(NoHandlerFoundException.class)
+    public ResponseVo<String> exception(NoHandlerFoundException exception){
+    	logger.warn("地址异常: {}", exception.getMessage());
+    	return ResponseVo.build(CodeEnum.C404);
     }
     
     /**
@@ -84,9 +83,8 @@ public class ExceptionConfig {
      * @return
      */
     @ExceptionHandler(Exception.class)
-    public @ResponseBody ResponseVo<String> exception(Exception exception){
+    public ResponseVo<String> exception(Exception exception){
     	logger.error("服务异常", exception);
-    	mailService.sendMail("【" + application + "】服务异常", MailSendVo.exception(exception));
     	return ResponseVo.build(CodeEnum.C500);
     }
     

+ 11 - 8
src/main/java/com/llisoft/sms/config/SpringMvcConfig.java

@@ -1,6 +1,7 @@
 package com.llisoft.sms.config;
 
 import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@@ -13,15 +14,17 @@ public class SpringMvcConfig implements WebMvcConfigurer {
 	
 	@Override // 默认首页
 	public void addViewControllers(ViewControllerRegistry registry) {
-			registry.addRedirectViewController("/", "/swagger-ui.html");
+		registry.addRedirectViewController("/", "/swagger-ui.html");
 	}
 
-//	@Override // 跨域配置
-//	public void addCorsMappings(CorsRegistry registry) {
-//    	registry.addMapping("/**")
-//	        .allowedOrigins("*")
-//	        .allowedHeaders("*")
-//	        .allowedMethods("POST", "OPTIONS");
-//	}
+	@Override // 静态资源访问
+	public void addResourceHandlers(ResourceHandlerRegistry registry) {
+		// 此处手动配置swagger静态资源映射关系,是由于application.yml中配置了spring.resources.addMappings: false,不使用springboot的默认静态资源配置
+		// 目的是让spingmvc遇到401或404等错误时可以直接把异常抛出而不重定向到/error返回页面,这样所有的异常都会在@ControllerAdvice中统一处理
+		// 但这样导致swagger静态资源无法访问,so,需要手动配置之
+		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+		WebMvcConfigurer.super.addResourceHandlers(registry);
+	}
 	
 }

+ 7 - 2
src/main/resources/application.yml

@@ -3,7 +3,7 @@ mta:
   debug: true #是否测试(测试模式不发邮件)
   emails: sunlin@mtavip.com, yangjie@mtavip.com #管理员邮箱
 
-##服务配置
+##端口配置
 server.port: 8002 #监听端口
   
 ##短信配置
@@ -31,7 +31,7 @@ spring.redis:
   password: 
   timeout: 1000
            
-##应用配置
+##服务名称
 spring.application.name: mta-service-sms #服务名称
   
 ##注册中心配置
@@ -57,6 +57,11 @@ management:
   endpoints.web.exposure.include: "*" #开启所有端点
   endpoint.health.show-details: always #显示健康详情
   
+
+##系统异常配置
+spring.resources.addMappings: false #不为工程中的资源文件建立映射
+spring.mvc.throwExceptionIfNoHandlerFound: true #出现异常时直接抛出,使@RestControllerAdvice可以处理404等异常(需要上面配置false才能生效)
+  
   
 ##日志配置
 logging: