Spring boot統合処理Filter異常

16107 ワード

Filter例外Spring MVCでは統一処理ができないため、例外定義の1つのFilterを手動で処理する必要があります.このFilterはすべてのFilterの先頭にあり、他のFilterで異常が発生した場合、例外スタックをキャプチャし、ErrorControllerに転送します.
@Slf4j
public class ExceptionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("ex filter init .......");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //          ,     
        boolean isRethrow = !Objects.isNull(request.getAttribute(Req.Attr.EX));
        if (isRethrow) {
            chain.doFilter(request, response);
            return;
        }
        try {
            chain.doFilter(request, response);
        } catch (AbstractCustomException e) {
            //     ,     
            request.setAttribute(Req.Attr.EX, e);
            request.getRequestDispatcher(UrlUtil.ERROR_RETHROW).forward(request, response);
        }
    }

    @Override
    public void destroy() {

    }
}

Filterを最初に登録
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ExceptionFilter exceptionFilter() {
        return new ExceptionFilter();
    }

    @Bean
    public FilterRegistrationBean registerExceptionFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(exceptionFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(1);
        return bean;
    }

ErrorControllerは次のようになります.
@RestController
public class ErrorController {

    @Resource
    private HttpServletRequest request;

    /**
     *       
     */
    @RequestMapping("/error/rethrow")
    public void rethrow() {
        throw ((AbstractCustomException) request.getAttribute(Req.Attr.EX));
    }
}

ErrorControllerが投げ出した例外はSpringのグローバル例外処理によってキャプチャされる
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     *       
     * @param e   
     * @return     
     */
    @ExceptionHandler(LoginException.class)
    @ResponseBody
    public Result<String> loginExceptionHandler(LoginException e) {
        OperatorContext.remove();
        log.error("    ", e);
        return Result.loginError(e.getMessage());
    }

    /**
     *       
     * @param e   
     * @return     
     */
    @ExceptionHandler(BizException.class)
    @ResponseBody
    public Result<String> bizExceptionHandler(BizException e) {
        log.error("    ", e);
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(LawlessInvokeException.class)
    @ResponseBody
    public Result<String> lawlessException(LawlessInvokeException e) {
        log.error("@    @", e);
        return Result.error(e.getMessage());
    }

    /**
     *       
     * @param e   
     * @return     
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result<String> exceptionHandler(Exception e) {
        log.error("     ", e);
        return Result.error("     ");
    }

これでFilterで他の場所と同じように異常を投げ出すことができます