为什么我的Http Filter会产生无限循环?

时间:2015-02-28 14:10:23

标签: java filter servlet-filters

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

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时,我的过滤器无限执行。为什么?

由于

1 个答案:

答案 0 :(得分:1)

您的过滤器配置为在对FORWARD形式的某个网址执行/referral/*时执行。当您转发到具有该表单的URL时,从您的过滤器代码中,您的过滤器会再次执行,并且一次又一次地执行,因此您有一个inifinte递归。

尝试从此行中删除DispatcherType.FORWARD

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

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

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

chain.doFilter(request, response);

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