【问题标题】:Why my Http Filter makes an infinite loop?为什么我的 Http 过滤器会无限循环?
【发布时间】:2015-05-01 04:52:44
【问题描述】:

我想实现一个 Http 过滤器来拦截对我的网站发出的一些请求。我想拦截对http://www.mywebsite.com/referral/userid 的请求。我编写了以下过滤器类:

public class ReferralFilter implements Filter{


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
         HttpServletRequest httpRequest = (HttpServletRequest) request;
            String contextPath = ((HttpServletRequest) request).getContextPath();
            String requestURI = httpRequest.getRequestURI();

            requestURI = StringUtils.substringAfter(requestURI, contextPath);
            if(StringUtils.contains(requestURI, "/referral/")){
                String referralIdentifier = StringUtils.substringAfter(requestURI, contextPath+"/referral/");
                //Search the referral's user
                if(referralIdentifier!=null && referralIdentifier.length()==12){

                        String cookieKey = "website.referral";
                        String cookieValue = referralIdentifier;
                        Cookie cookie = new Cookie(cookieKey,cookieValue);
                        cookie.setMaxAge(60*60*24*365);
                        ((HttpServletResponse) response).addCookie(cookie);
                        //redirect to the home page angularJS app
                        requestURI = StringUtils.substringBeforeLast(requestURI,"/referral/")+"#";



                }


            }

            String newURI = requestURI;
            request.getRequestDispatcher(newURI).forward(request, response);

    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

这是我的配置:

@Configuration
@AutoConfigureAfter(CacheConfiguration.class)
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {

    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);

    @Inject
    private Environment env;

    @Autowired(required = false)
    private MetricRegistry metricRegistry;

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        log.info("Web application configuration, using profiles: {}", Arrays.toString(env.getActiveProfiles()));
        EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);

        // some initializations

        initReferralFilter(servletContext,disps);
        log.info("Web application fully configured");
    }



    /**
     * Initializes the Referral filter.
     */
    private void initReferralFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
        log.debug("Registering Referral Filter");
        FilterRegistration.Dynamic referralFilter = servletContext.addFilter("referralFilter", new ReferralFilter());
        referralFilter.addMappingForUrlPatterns(disps, true, "/referral/*");
           }

    // other methods
}

当我尝试访问http://www.mywebsite.com/referral/eRfdg54GDGd2 时,我的过滤器会无限执行。为什么?

谢谢

【问题讨论】:

    标签: java filter servlet-filters


    【解决方案1】:

    您的过滤器配置为在对格式为 /referral/* 的某个 URL 执行 FORWARD 时执行。当您从过滤器代码中转发到具有该表单的 URL 时,您的过滤器会一次又一次地执行,等等,所以您有一个无限递归。

    尝试从此行中删除DispatcherType.FORWARD

    EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
    

    另一种方法是更改​​您的应用程序 URL,以便您转发到未被过滤器拦截的 URL。

    除此之外,您永远不会让过滤器链继续下去。如果您不想中断您的请求,则必须将此行放在您的 doFilter() 方法中:

    chain.doFilter(request, response);
    

    我不知道你是否要让链条继续下去,这只是为了澄清。

    【讨论】:

    • 我已经按照你的建议删除了。所以无限循环消失了。伟大的 !但我想通过将 url 从mywebsite.com/referral/userid 更改为mywebsite.com/# 来继续。你有什么想法吗?
    • 您要更改过滤器截获的 URL 还是整个应用程序的 URL?
    • 当用户点击 mywebsite.com/referral/userid => 过滤器执行:在过滤器中我想重定向主页上的用户(其 url 是 mywebsite.com/#/)。
    • 尝试将requestURI = StringUtils.substringBeforeLast(requestURI, "/referral/") + "#"; 更改为requestURI = contextPath + "#";(或者可能是to just "/#"`)。
    • 我试过了,但我有 404 错误,浏览器中的 url 没有改变。它总是 mywebsite.com/referral/userid
    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 2017-09-21
    • 2016-08-01
    相关资源
    最近更新 更多