zoukankan      html  css  js  c++  java
  • spring boot 捕获filter异常 统一返回处理结果

    如前面的文章所述,controller中抛出的异常我们使用ControllerAdvice来处理:

    @RestControllerAdvice
    @Slf4j
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(value = Exception.class)
        public AjaxResponse handler(Exception e){
            AjaxResponse r = new AjaxResponse();
            if (e instanceof RuntimeException){
                RuntimeException selectNoFindException = (RuntimeException) e;
                r.setStatus(-1);
                r.setMsg(selectNoFindException.getMessage());
            } else {
                r.setStatus(-1);
                r.setMsg("系统错误");
            }
            log.error(e.getMessage());
            return r;
        }
    
        /**
         * 捕获自定义异常
         * @param e
         * @return
         */
        @ExceptionHandler(value = FriendlyException.class)
        public Map<String,Object> errorHandle(FriendlyException e){
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("code",e.getCode());
            map.put("msg",e.getMsg());
            return map;
        }
    }

    但是filter中抛出的异常上面的方法就为无能为力了,如登录的认证,和权限的判断,我们可以使用如下的处理方法:

    定义一个controller 继承BasicErrorController,并重写error方法。

    @RestController
    @Api(value = "handle filter throws exception", description = "处理filter抛出的异常")
    public class ErrorController extends BasicErrorController {
    
        public ErrorController() {
            super(new DefaultErrorAttributes(), new ErrorProperties());
        }
    
        @Override
        @RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
        public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
            Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
            HttpStatus status = getStatus(request);
    
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("code",body.get("status"));
            map.put("msg",body.get("message"));
            return new ResponseEntity<Map<String, Object>>(map, status);
        }
    }

    看下request中的信息:

    看一下body中的信息:

    接下来就可以filter中抛出异常,errorcontroller就可以捕获了:

     以下是shiro中认证失败时方法onAccessDenied:

        protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
            HttpServletResponse httpResponse = WebUtils.toHttp(servletResponse);
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setContentType("application/json;charset=UTF-8");
            httpResponse.setStatus(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION);
    
            fillCorsHeader(WebUtils.toHttp(servletRequest), httpResponse);
    
            throw new AuthenticationException("token认证失败");
            //return false;
        }

    以下是权限判断时,权限不足时抛出的异常在isAccessAllowed方法中。

        protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) throws Exception {
            Subject subject = getSubject(servletRequest, servletResponse);
            String[] rolesArray = (String[]) mappedValue;
            //没有角色限制,有权限访问
            if (rolesArray == null || rolesArray.length == 0) {
                return true;
            }
            for (String role : rolesArray) {
                //若当前用户是rolesArray中的任何一个,则有权限访问
                if (subject.hasRole(role)) {
                    return true;
                }
            }
            throw new AuthorizationException("没有权限访问此资源");
        }

    这里isAccessAllowed和onAccessDenied应该在哪个方法抛出异常呢,我没有考虑太多,都试了一下,有机会时再研究一下

  • 相关阅读:
    运算符重载
    责任链模式
    MFC一些常见面试问题
    浅拷贝&深拷贝
    下雨的效果
    本地时间使用与倒计时
    钟表效果
    一种水纹波浪效果
    一个相册效果
    在Flash中管理鼠标右键
  • 原文地址:https://www.cnblogs.com/hankuikui/p/10522375.html
Copyright © 2011-2022 走看看