springboot全局捕获异常并返回页面

1.新建异常类MyException,注意必须继承RuntimeException

public class MyException extends RuntimeException{
    /** serialVersionUID*/
    private static final long serialVersionUID = -5212079010855161498L;

    public MyException(String message){
        super(message);
        this.message = message;
    }

    //异常信息
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }
}

2. 在代码中抛出异常

@Component
@Aspect
public class Interceptor {
    private static final Log LOGGER = LogFactory.getLog(Interceptor.class);
    @Autowired
    private LogService logService;
    private static final String NAMESPACE = "API/";
    /**
     * 调用接口前拦截
     * @param MyInteceptor
     */
    @Before("@annotation(importOperate)")
    @Around("execution(* com.cmbchina.ccd.oa.socialsecurity.controller.*Controller.*(..))")
    private void pointcut(MyInteceptor myInteceptor) {
        String operateName = myInteceptor.operateName();
        if(StringUtils.isBlank(operateName) || "before".equals(operateName)){
            throw new MyException("我的异常");
        }
    }

    /**
     * 记录日志
     *
     * @param joinPoint 切面连接点
     *                  整个表达式可以分为五个部分:
     *                  1、execution(): 表达式主体。
     *                  2、第一个*号:表示返回类型,*号表示所有的类型。
     *                  3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.cmbchina.ccd.oa.hrtransfer.controller包、子孙包下所有类的方法。
     *                  4、第二个*号:表示类名,*号表示所有的类。
     *                  5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
     * @return 统一返回报文
     * @throws Throwable
     */

    @Around("execution(* com.cmbchina.ccd.oa.socialsecurity.controller.*Controller.*(..))")
    public Object logInfo(ProceedingJoinPoint joinPoint) {
        //拦截的实体类
        Object target = joinPoint.getTarget();
        //拦截的方法名称
        String methodName = joinPoint.getSignature().getName();
        //拦截的方法参数
        Object[] args = joinPoint.getArgs();
        Class clazz = target.getClass();
        //判断是否存在requestMapping注释
        String path = getNameSpace(clazz);
        //添加日志
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        AccessLog accessLog = new AccessLog();
        //只记录对外暴露的接口日志
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        accessLog.setCreateTime(new Date());
        accessLog.setAccessUrl(methodName);
        if ("get".equalsIgnoreCase(request.getMethod())) {
            accessLog.setParameter(request.getQueryString());
        } else {
            if (args != null && args.length > 0) {
                accessLog.setParameter(JSON.toJSONString(args[0]));
            }
        }
        try {
            Object result = joinPoint.proceed();
            if (path != null || result != null) {
                accessLog.setReturnMsg(JSON.toJSONString(result));
                stopWatch.stop();
                accessLog.setAccessDuration(stopWatch.getTime());
                accessLog.setType(Constant.LogType.LOCAL_SYSTEM);
                //获取登录人不需要记录日志
                List<String> noLogRecord = Arrays.asList("Employee");
                if(!noLogRecord.contains(path)){
                    logService.createLog(accessLog);
                }
            }
            return result;
        } catch (Throwable exp) {
            //异常日志
            StringBuffer sb = new StringBuffer();
            StackTraceElement[] stackArray = exp.getStackTrace();
            for (int i = 0; i < stackArray.length; i++) {
                StackTraceElement element = stackArray[i];
                sb.append(element.toString() + "\n");
            }
            accessLog.setType(Constant.LogType.LOCAL_SYSTEM_EXCEPTION);
            accessLog.setReturnMsg(sb.toString());
            logService.createLog(accessLog);
            LOGGER.error(sb.toString());
            exp.printStackTrace();
            throw new MyException(exp.getMessage());
            //return null;
        }
    }


    /**
     * 调用接口后拦截
     * @param myInteceptor
     */
    @AfterReturning(returning="result", pointcut="@annotation(myInteceptor)")
    public void after(Object result, MyInteceptor myInteceptor){
        Response response = (Response) result;
        String operateName = myInteceptor.operateName();
        if(StringUtils.isBlank(operateName) || "after".equals(operateName)){
            if(response != null){
                
            }
        }
    }
    /**
     * 获取拦截类的命名空间
     *
     * @param clazz
     * @return
     */
    private String getNameSpace(Class clazz) {
        String path = null;
        boolean present = clazz.isAnnotationPresent(RequestMapping.class);
        if (present) {
            //得到requestMapping注释
            RequestMapping annotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
            //得到value数组

            String[] pathArr = annotation.value();
            for (String str : pathArr) {
                if (path == null) {
                    path = str;
                } else {
                    path += str;
                }

            }
        }
        return path;
    }
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyInteceptor {
    String operateName() default "";
}

4.全局捕获异常

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public Object defaultErrorHandler(Exception e){
        e.printStackTrace();
        return e.getMessage();
    }
    // 处理方法参数的异常类型
    @ExceptionHandler()
    public Object exceptionHandle(Exception e){
        e.printStackTrace();
        return e.getMessage();
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

裂魂人1214

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值