javaurl-rewritingservlet-filterstuckey-urlrewrite-filter

Custom filter extending UrlRewriteFilter to load rules from database


I have custom redirection filters in my project, which are loading defined rules from database, and handle redirections.

In addition to those, I use also UrlRewriteFilter , with some rules defined in urlrewrite.xml.

Now I want to switch completely to use tuckey's filter, however I want to load rules from my database, instead of having them defined in xml (so that I can have single place to keep redirection rules).

My idea is to extend UrlRewriteFilter, and instead of initializing rules from XML files, load my rules from database.

Here is what I have so far,

@Service
public class CustomUrlRewriteFilter extends UrlRewriteFilter {

    @Autowired
    private RedirectService redirectService;

    private UrlRewriter urlRewriter;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        super.init(filterConfig);
    }

    @Override
    protected UrlRewriter getUrlRewriter(ServletRequest request, ServletResponse response, FilterChain chain) {
        return urlRewriter;
    }

    @PostConstruct
    public void initUrlRewriter() {

        List<Redirect> redirects = redirectService.retrieveAll();

        Conf conf = new Conf();

        for (Redirect redirect : redirects) {
            NormalRule rule = new NormalRule();

            rule.setMatchType(redirect.getMatchType());
            rule.setToType(redirect.getRedirectType());
            rule.setFrom(redirect.getPath());
            rule.setTo(redirect.getTarget());
            rule.setQueryStringAppend("true");
            conf.addRule(rule);
        }

        conf.setUseQueryString(true);

        urlRewriter = new UrlRewriter(conf);

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
                                                                                             ServletException {
        super.doFilter(req, resp, chain);
    }

}

The problem is, redirection is not happening, I do not get any exception. When I debug, I can see that when processing request it returns false, as it can't find a rule chain (could it be that I need to init somehow rule chain?).

I assume I miss something to override, or my initialization is wrong. Does anyone has an experience on this? Is it possible to achieve proper behavior at all?

Any help is appreciated.


Solution

  • So finally I could manage to get this work.

    The problem was that adding rules to the Conf is not enough, I had to also initilize those rules by calling conf.initialise().

    On the other side, conf.initialise() itself calls NormalRule.initialise() which is checking the existence and validity of urlrewrite.xml, and if it does not properly initilized it returns false and the configuration is not initilizing properly.

    The workaround is to provide custom rule extending NormalRule.initialise(), which explicitly returns always true when calling it's initialise().

    Here is the example of custom rule

    public final class CustomRule extends NormalRule {
    
        public CustomRule(RedirectType redirectType, MatchType matchType, String from, String to) {
            super();
    
            setMatchType(matchType);
            setToType(redirectType);
    
            setFrom(from);
            setTo(to);
            setQueryStringAppend("true");
        }
    
        @Override
        public boolean initialise(ServletContext context) {
            super.initialise(context);
            return true;
        }
    
    }
    

    And then when creating UrlRewriter I need to initiliaze the configuration, and that's it.

    @Service
    public class CustomUrlRewriteFilter extends UrlRewriteFilter {
    
        @Autowired
        private RedirectService redirectService;
    
        private UrlRewriter urlRewriter;
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            super.init(filterConfig);
        }
    
        @Override
        protected UrlRewriter getUrlRewriter(ServletRequest request, ServletResponse response, FilterChain chain) {
            return urlRewriter;
        }
    
        @PostConstruct
        public void initUrlRewriter() {
    
            List<Redirect> redirects = redirectService.retrieveAll();
    
            Conf conf = new Conf();
    
            for (Redirect redirect : redirects) {
                CustomRule rule = new CustomRule(
                        redirect.getRedirectType(), redirect.getMatchType(), redirect.getPath(), redirect.getTarget()
                );
                conf.addRule(rule);
            }
    
            conf.setUseQueryString(true);
    
            conf.initialise();
    
            urlRewriter = new UrlRewriter(conf);
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
                                                                                                 ServletException {
            super.doFilter(req, resp, chain);
        }
    
        @Override
        public void destroy() {
            super.destroy();
        }
    
    }
    

    Still: Comments are welcomed.