gpt4 book ai didi

SpringBoot搭建全局异常拦截

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章SpringBoot搭建全局异常拦截由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1.异常拦截类的创建

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.liqi.web.core.exception;
 
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
 
import com.liqi.common.base.Constants;
import com.liqi.common.base.ResultBean;
import com.liqi.common.exception.BusinessInterfaceException;
import com.liqi.common.exception.bean.ErrorBean;
 
import lombok.extern.slf4j.Slf4j;
 
/**
  * 自定义异常处理器
  *
  * @author ieflex
  */
@RestControllerAdvice
@Slf4j
public class InterfaceExceptionHandler {
 
     /**
      * 接口 业务异常
      */
     @ResponseBody
     @ExceptionHandler (BusinessInterfaceException. class )
     public String businessInterfaceException(BusinessInterfaceException e) {
         log.error(e.getMessage(), e);
         ErrorBean error = e.getError();
         ResultBean resultBean = new ResultBean(error.hashCode(), error.getErrorMsg());
         return resultBean.toString();
     }
 
     /**
      * 拦截所有运行时的全局异常   
      */
     @ExceptionHandler (RuntimeException. class )
     @ResponseBody
     public String runtimeException(RuntimeException e) {
         log.error(e.getMessage(), e);
         // 返回 JOSN
         ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT);
         return resultBean.toString();
     }
 
     /**
      * 系统异常捕获处理
      */
     @ExceptionHandler (Exception. class )
     @ResponseBody
     public String exception(Exception e) {
         log.error(e.getMessage(), e);
         ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT);
         // 返回 JOSN
         return resultBean.toString();
     }
}

2.controller 测试

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.springboot_Error.ErrorController;
        
         import org.springframework.stereotype.Controller;
         import org.springframework.web.bind.annotation.RequestMapping;
        
         @Controller
         public class ErrorControllerTest {
             //全局异常拦截 测试
             @RequestMapping ( "/ErrorTest" )
             public String index2(){
                 System.err.println( "请求成功!" );
                 int i = 1 / 0 ; //这里会有一个运算异常
                 return "index" ;
             }
            
         }

3.启动 springboot 工程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.springboot_Error.ErrorRun;
        
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
 
        
         //扫描 com.springboot_Error.ErrorController 包下 controller 注解过的类
         @ComponentScan (basePackages={ "com.springboot_Error.ErrorController" })
         @EnableAutoConfiguration
         public class ErrorRun {
            
             public static void main(String[] args) {
                 SpringApplication.run(ErrorRun. class , args);
             }
            
         }

4.测试

?
1
2
3
4
5
6
7
8
/**
  * 功能描述: 模拟自定义异常
  * @return
  */
@RequestMapping (value = "/api/test"
public Object myext() {
     throw new BusinessInterfaceException( "500" , "my ext异常" );
}

经过测试发现可以捕获到Controller层的异常,当前前提是Controller层没有对异常进行catch处理,如果Controller层对异常进行了catch处理,那么在这里就不会捕获到Controller层的异常了,所以这一点要注意.

5.基于Springboot自身的全局异常统一处理

主要是实现ErrorController接口或者继承AbstractErrorController抽象类或者继承BasicErrorController类 。

以下是网上一位博主给出的示例代码,博客地址为:https://blog.csdn.net/king_is_everyone/article/details/53080851 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
@Controller
@RequestMapping (value = "error" )
@EnableConfigurationProperties ({ServerProperties. class })
public class ExceptionController implements ErrorController {
 
     private ErrorAttributes errorAttributes;
 
     @Autowired
     private ServerProperties serverProperties;
 
 
     /**
      * 初始化ExceptionController
      * @param errorAttributes
      */
     @Autowired
     public ExceptionController(ErrorAttributes errorAttributes) {
         Assert.notNull(errorAttributes, "ErrorAttributes must not be null" );
         this .errorAttributes = errorAttributes;
     }
 
 
     /**
      * 定义404的ModelAndView
      * @param request
      * @param response
      * @return
      */
     @RequestMapping (produces = "text/html" ,value = "404" )
     public ModelAndView errorHtml404(HttpServletRequest request,
                                   HttpServletResponse response) {
         response.setStatus(getStatus(request).value());
         Map<String, Object> model = getErrorAttributes(request,
                 isIncludeStackTrace(request, MediaType.TEXT_HTML));
         return new ModelAndView( "error/404" , model);
     }
 
     /**
      * 定义404的JSON数据
      * @param request
      * @return
      */
     @RequestMapping (value = "404" )
     @ResponseBody
     public ResponseEntity<Map<String, Object>> error404(HttpServletRequest request) {
         Map<String, Object> body = getErrorAttributes(request,
                 isIncludeStackTrace(request, MediaType.TEXT_HTML));
         HttpStatus status = getStatus(request);
         return new ResponseEntity<Map<String, Object>>(body, status);
     }
 
     /**
      * 定义500的ModelAndView
      * @param request
      * @param response
      * @return
      */
     @RequestMapping (produces = "text/html" ,value = "500" )
     public ModelAndView errorHtml500(HttpServletRequest request,
                                   HttpServletResponse response) {
         response.setStatus(getStatus(request).value());
         Map<String, Object> model = getErrorAttributes(request,
                 isIncludeStackTrace(request, MediaType.TEXT_HTML));
         return new ModelAndView( "error/500" , model);
     }
 
 
     /**
      * 定义500的错误JSON信息
      * @param request
      * @return
      */
     @RequestMapping (value = "500" )
     @ResponseBody
     public ResponseEntity<Map<String, Object>> error500(HttpServletRequest request) {
         Map<String, Object> body = getErrorAttributes(request,
                 isIncludeStackTrace(request, MediaType.TEXT_HTML));
         HttpStatus status = getStatus(request);
         return new ResponseEntity<Map<String, Object>>(body, status);
     }
 
 
     /**
      * Determine if the stacktrace attribute should be included.
      * @param request the source request
      * @param produces the media type produced (or {@code MediaType.ALL})
      * @return if the stacktrace attribute should be included
      */
     protected boolean isIncludeStackTrace(HttpServletRequest request,
                                           MediaType produces) {
         ErrorProperties.IncludeStacktrace include = this .serverProperties.getError().getIncludeStacktrace();
         if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
             return true ;
         }
         if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {
             return getTraceParameter(request);
         }
         return false ;
     }
 
 
     /**
      * 获取错误的信息
      * @param request
      * @param includeStackTrace
      * @return
      */
     private Map<String, Object> getErrorAttributes(HttpServletRequest request,
                                                    boolean includeStackTrace) {
         RequestAttributes requestAttributes = new ServletRequestAttributes(request);
         return this .errorAttributes.getErrorAttributes(requestAttributes,
                 includeStackTrace);
     }
 
     /**
      * 是否包含trace
      * @param request
      * @return
      */
     private boolean getTraceParameter(HttpServletRequest request) {
         String parameter = request.getParameter( "trace" );
         if (parameter == null ) {
             return false ;
         }
         return ! "false" .equals(parameter.toLowerCase());
     }
 
     /**
      * 获取错误编码
      * @param request
      * @return
      */
     private HttpStatus getStatus(HttpServletRequest request) {
         Integer statusCode = (Integer) request
                 .getAttribute( "javax.servlet.error.status_code" );
         if (statusCode == null ) {
             return HttpStatus.INTERNAL_SERVER_ERROR;
         }
         try {
             return HttpStatus.valueOf(statusCode);
         }
         catch (Exception ex) {
             return HttpStatus.INTERNAL_SERVER_ERROR;
         }
     }
 
     /**
      * 实现错误路径,暂时无用
      * @see ExceptionMvcAutoConfiguration#containerCustomizer()
      * @return
      */
     @Override
     public String getErrorPath() {
         return "" ;
     }
 
}

6.AOP也可以实现异常的全局处理

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Component
@Aspect
public class ExceptionAspectController {
     public static final Logger logger = LoggerFactory.getLogger(ExceptionAspectController. class );
 
     @Pointcut ( "execution(* com.test.test.*.*(..))" ) //此处基于自身项目的路径做具体的设置
     public void pointCut(){}
 
     @Around ( "pointCut()" )
     public Object handleControllerMethod(ProceedingJoinPoint pjp) {
         Stopwatch stopwatch = Stopwatch.createStarted();
 
         APIResponse<?> apiResponse;
         try {
             logger.info( "执行Controller开始: " + pjp.getSignature() + " 参数:" + Lists.newArrayList(pjp.getArgs()).toString());
             apiResponse = (APIResponse<?>) pjp.proceed(pjp.getArgs());
             logger.info( "执行Controller结束: " + pjp.getSignature() + ", 返回值:" + apiResponse.toString());
             logger.info( "耗时:" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒)." );
         } catch (Throwable throwable) {
             apiResponse = handlerException(pjp, throwable);
         }
 
         return apiResponse;
     }
 
     private APIResponse<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
         APIResponse<?> apiResponse = null ;
         if (e.getClass().isAssignableFrom(MessageCenterException. class ) ){
             MessageCenterException messageCenterException = (MessageCenterException)e;
             logger.error( "RuntimeException{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + messageCenterException.getException().getMessage() + "}" , e);
             apiResponse = messageCenterException.getApiResponse();
         } else if (e instanceof RuntimeException) {
             logger.error( "RuntimeException{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}" , e);
             apiResponse = new APIResponse(APIResponse.FAIL, null ,e.getMessage());
         } else {
             logger.error( "异常{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}" , e);
             apiResponse = new APIResponse(APIResponse.FAIL, null ,e.getMessage());
         }
 
         return apiResponse;
     }
}

到此这篇关于SpringBoot搭建全局异常拦截的文章就介绍到这了,更多相关Springboot全局异常内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。

原文链接:https://blog.csdn.net/ieflex/article/details/90644976 。

最后此篇关于SpringBoot搭建全局异常拦截的文章就讲到这里了,如果你想了解更多关于SpringBoot搭建全局异常拦截的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com