springboot 拦截器和过滤器的取舍?

Apple
  • 277

目前要实现功能如下:

当前项目有三个接口允许被访问,其他的接口不允许访问

三个接口如下
image.png

image.png

image.png

且接口中不允许有querParam 且body中不允许有参数

目前实现方式考虑了两种使用拦截器 或者 过滤器

拦截器的代码如下:

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JumpUrlInterceptor jumpUrlInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jumpUrlInterceptor).addPathPatterns("/**");
        super.addInterceptors(registry);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        String os = System.getProperty("os.name");
        super.addResourceHandlers(registry);
    }
}
@Component
public class JumpUrlInterceptor implements HandlerInterceptor {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object o) {
        String requestURI = req.getRequestURI();
        if(requestURI.startsWith("/jump/app/")){
            logger.info("正在检查pathVariable: appCode");
            Map pathVariables = (Map) req.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            String appCode = (String)pathVariables.get("appCode");
            /* 2.判断是否IDP登录 */
            AppAddrMapping appAddrMapping = AppAddrMapping.ADDR_MAPPING_MAP.get(appCode);
            if (null == appAddrMapping) {
                logger.error("当前url中的appCode : {} 和app.json中的不相匹配,请检查配置文件",appCode);
                throw new ConfArgException("app不存在,请检查appcode是否正确");
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView mav) {

    }

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse rep, Object o, Exception e) {

    }

请问这样写是否有问题,url请求过滤是否放到filter中比较好?

filter代码如下:

@Configuration
public class SecurityCheckFilter {

    @Bean
    public FilterRegistrationBean registFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new UrlCheckFilter());
        registration.addUrlPatterns("/*");
        registration.setName("urlCheckFilter");
        registration.setOrder(1);
        return registration;
    }

}
public class UrlCheckFilter implements Filter {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // do something 处理request 或response
        // doFilter()方法中的servletRequest参数的类型是ServletRequest,需要转换为HttpServletRequest类型方便调用某些方法

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        boolean requri1 = request.getRequestURI().startsWith("/jump/app");
        boolean requri2 = request.getRequestURI().startsWith("/jump/setCookie");
        boolean requri3 = request.getRequestURI().startsWith("/jump/callback");
        if (!requri1 && !requri2 && !requri3) {
            return;
        }
        String queryString = request.getQueryString();
        if (StringUtils.isNotEmpty(queryString)) {
            return;
        }

        BufferedReader br;
        try {
            br = request.getReader();
            String str, wholeStr = "";
            while((str = br.readLine()) != null){
                wholeStr += str;
            }
            if(StringUtils.isNotEmpty(wholeStr)){
               return;
            }
        } catch (IOException e1) {
            logger.error(""+e1);
        }

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

求个大佬指正下 这样写是否有问题:

回复
阅读 773
3 个回答

如果对执行顺序没有严苛的要求,一般是没有区别的,不过有一点倒是用拦截器比filter舒服一点的,最起码代码出了问题,会走mvc的全局异常处理,filter就需要你自己处理了

servlet filter 和 spring mvc interceptor 都可以的,不过从执行顺序来看,filter 在前,而且在 springmvc 的 dispatch之前,而 interceptor在后,所以具体用哪个,取决于你的需求,是对顺序有要求,是否有前置的 servlet/filter 干扰?

相关问题可以尝试使用spring security来实现,方便快捷

宣传栏