简体   繁体   中英

Why my Http Filter makes an infinite loop?

I want to implement a Http Filter to intercept some requests made to my website. I want to intercept request to http://www.mywebsite.com/referral/userid . I write the following Filter class:

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

    }

}

Here is my configuration :

@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
}

When i try to access to http://www.mywebsite.com/referral/eRfdg54GDGd2 my filter executes infinitely. Why ?

Thanks

Your filter is configured to execute when a FORWARD is performed to some URL with the form /referral/* . As you're forwarding to an URL with that form, from within your filter code, your filter gets executed again, and again and again, etc, so you have an inifinte recursion.

Try removing the DispatcherType.FORWARD from this line:

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

Another approach would be to change your application URLs, so that you forward to an URL that is not intercepted by your filter.

Apart from that, you're never letting the filter chain continue. If you don't want to interrupt your request, you must place this line in your doFilter() method:

chain.doFilter(request, response);

I don't know whether you want to let the chain continue or not, this is just to clarify.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM