SpringBoot搭建全局异常拦截

网友投稿 283 2023-01-02

SpringBoot搭建全局异常拦截

1.异常拦截类的创建

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 测试

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 工程

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.测试

/**

* 功能描述: 模拟自定义异常

* @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

@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 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> error404(HttpServletRequest request) {

Map body = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

HttpStatus status = getStatus(request);

return new ResponseEntity>(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 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> error500(HttpServletRequest request) {

Map body = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

HttpStatus status = getStatus(request);

return new ResponseEntity>(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 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也可以实现异常的全局处理

@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;

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot2.x 集成腾讯云短信的详细流程
下一篇:丫t圆通快递物流查询单号(丫t圆通快递查询单号丫t)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~