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.
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.