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應該在哪個方法拋出異常呢,我沒有考慮太多,都試了一下,有機會時再研究一下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM