美文网首页
ControllerAdvice或者RestController

ControllerAdvice或者RestController

作者: CoderLJW | 来源:发表于2020-07-01 10:39 被阅读0次

    项目中使用springboot Security的时候,配置的ControllerAdvice全局异常失效了

    正常使用全局异常捕获没有问题,我是这样使用的

    • GlobalExceptionHanlder
    //基于@ControllerAdvice注解的Controller层的全局异常统一处理
    @ControllerAdvice
    public class GlobalExceptionHanlder {
    
        private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHanlder.class);
    
        // Throwable是所有异常的父类
        @ResponseStatus(HttpStatus.OK)
        @ExceptionHandler(value = Throwable.class)
        @ResponseBody
        public RestResponse<Object> handler(HttpServletRequest req, Throwable throwable){
            String errmsg = throwable.getMessage();
            StackTraceElement[] stackTraceElements = throwable.getStackTrace();
            if (stackTraceElements.length != 0){
                StackTraceElement stackTraceElement = stackTraceElements[0];
                errmsg += "\n" + "问题出处:" + stackTraceElement.toString();
            }
            logger.error(errmsg, throwable);
            RestCode restCode = Exception2CodeRepo.getCode(throwable);
            RestResponse<Object> response = RestResponse.error(restCode);
            return response;
        }
    }
    
    • Exception2CodeRepo,这类是把常出现的异常统一识别处理了
    public class Exception2CodeRepo {
        private static Object getType(Throwable throwable) {
            try {
                return FieldUtils.readDeclaredField(throwable, "type", true);
            } catch (Exception e) {
                return null;
            }
        }
        public static RestCode getCode(Throwable throwable) {
            if (throwable == null) {
                return RestCode.UNKNOWN_ERROR_NULL;
            }
            RestCode restCode = exceptionType(throwable);
            return restCode;
        }
        private static RestCode exceptionType(Throwable throwable){
            /**
             * HttpMediaTypeNotSupportedException
             */
            String exceptionString = throwable.toString();
            if (exceptionString.contains("HttpMessageConversionException")){
                return RestCode.PARSMS_TYPE_ERROR;
            }else if (exceptionString.contains("NullPointerException")
                    || exceptionString.contains("BeanPropertyBindingResult")
                    || exceptionString.contains("MissingServletRequestParameterException")
                    || exceptionString.contains("MethodArgumentNotValidException")){
                return RestCode.ParamsAndInstanceIsNull;
            }else if (exceptionString.contains("HttpMediaTypeNotSupportedException")){
                return RestCode.HttpMediaTypeNotSupportedException;
            }else if (exceptionString.contains("HttpRequestMethodNotSupportedException")){
                return RestCode.HttpRequestMethodNotSupportedException;
            }else if (exceptionString.contains("HttpMessageNotReadableException")
                    || exceptionString.contains("JsonParseException")
                    || exceptionString.contains("JSONException")){
                return RestCode.JsonParseException;
            }else if (exceptionString.contains("DuplicateKeyException")){
                return RestCode.RepeatAddData;
            }else if (exceptionString.contains("MissingServletRequestPartException")){
                return RestCode.NoNeedUploadFile;
            }else if (exceptionString.contains("请登录")){
                return RestCode.NoLogin;
            }else if (exceptionString.contains("请注册")){
                return RestCode.NoRegister;
            }else if (exceptionString.contains("登录已过期")){
                return RestCode.LoginTokenExpired;
            }else if (exceptionString.contains("token无效")){
                return RestCode.TokenInvalid;
            }
            return RestCode.UNKNOWN_ERROR;
        }
    }
    
    接下来出现问题了

    当你项目中使用springboot Security的时候,上面配置的全局异常失效了。这是因为Security的异常捕获覆盖了ControllerAdvice或者他们有冲突了导致失效,这个时候需要改变或者拦截Security的异常。【我在百度上,搞了好长时间,都没有找到问题,最后不得已去了google】

    • 1、处理如下,修改原来的全局异常,继承OncePerRequestFilter
    @Component
    public class GlobalExceptionHanlderFilter extends OncePerRequestFilter {
    
        private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHanlderFilter.class);
    
        public void handler(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Throwable throwable) throws IOException {
            String errmsg = throwable.getMessage();
            StackTraceElement[] stackTraceElements = throwable.getStackTrace();
            if (stackTraceElements.length != 0){
                StackTraceElement stackTraceElement = stackTraceElements[0];
                errmsg += "\n" + "问题出处:" + stackTraceElement.toString();
            }
            logger.error(errmsg, throwable);
            RestCode restCode = Exception2CodeRepo.getCode(throwable);
            RestResponse<Object> response = RestResponse.error(restCode);
    
            PrintWriterOut.writeOut(httpServletRequest, httpServletResponse, 200, response);
        }
        @Override
        protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
            try {
                filterChain.doFilter(httpServletRequest, httpServletResponse);
            }catch (Throwable e) {
                this.handler(httpServletRequest, httpServletResponse, e);
            }
        }
    }
    
    • 2、配置Security中的异常过滤器,直接覆盖这个bean就行。把自定义的过滤器添加进去
    @Bean
        public FilterRegistrationBean filterRegistrationBean() {
            FilterRegistrationBean bean = new FilterRegistrationBean();
            bean.setFilter(new GlobalExceptionHanlderFilter());
            // 任何接口路径都要执行
            bean.addUrlPatterns("/*");
            // 优先级最高
            bean.setOrder(Integer.MIN_VALUE);
            return bean;
        }
    

    项目测试没有问题,正常捕获异常,Security的权限、角色、账号密码异常还是Security自己处理

    相关文章

      网友评论

          本文标题:ControllerAdvice或者RestController

          本文链接:https://www.haomeiwen.com/subject/kvhcqktx.html