自定义过滤器扩展UrlRewriteFilter以从数据库加载规则

时间:2015-03-13 14:22:45

标签: java url-rewriting servlet-filters tuckey-urlrewrite-filter

我的项目中有自定义重定向过滤器,它们从数据库加载定义的规则,并处理重定向。

除此之外,我还使用UrlRewriteFilter,并在urlrewrite.xml中定义了一些规则。

现在我想完全切换到使用tuckey的过滤器,但是我想从我的数据库中加载规则,而不是在xml中定义它们(这样我就可以有一个单独的位置来保留重定向规则)。

我的想法是扩展UrlRewriteFilter,而不是从XML文件初始化规则,从数据库加载我的规则。

这是我到目前为止所拥有的,

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

}

问题是,重定向没有发生,我没有任何异常。当我调试时,我可以看到当processing request它返回false时,因为它找不到规则链(可能是我需要以某种方式初始化规则链吗?)。

我认为我错过了要覆盖的东西,或者我的初始化是错误的。有没有人有这方面的经验?是否有可能实现正确的行为?

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

所以最后我可以设法完成这项工作。

问题是向Conf添加规则是不够的,我还必须通过调用conf.initialise()来启动这些规则。

另一方面,conf.initialise()本身调用NormalRule.initialise()来检查urlrewrite.xml的存在性和有效性,如果它没有正确启动,则返回false并且配置没有正确启动。

解决方法是提供自定义规则扩展NormalRule.initialise(),在调用true时显式返回initialise()

以下是自定义规则

的示例
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;
    }

}

然后在创建UrlRewriter时,我需要初始化配置,这就是它。

@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();
    }

}

仍然:欢迎评论。

答案 1 :(得分:0)

就我而言,我想使用属性值来构建规则。我找到了一个更短的版本来实现与上述文章相同的功能。

@Component
public class CustomUrlRewriteFilter extends UrlRewriteFilter {

  @Value("${sites.cities.codes}")
  private String citiesCodes;

  @Override
  protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
    Conf conf = new Conf();

    NormalRule rule = new NormalRule();
    rule.setMatchType("regex");
    rule.setName("Remove City param");
    String from = "^/(" +  citiesCodes + ")/?(.*)$";
    rule.setFrom(from);
    rule.setTo("/$2");

    conf.addRule(rule);

    conf.initialise();
    checkConf(conf);
  }
}