Пользовательский фильтр, расширяющий UrlRewriteFilter для загрузки правил из базы данных

В моем проекте есть настраиваемые фильтры перенаправления, которые загружают определенные правила из базы данных и обрабатывают перенаправления.

В дополнение к ним я также использую 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);
    }

}

Проблема в том, что перенаправление не происходит, я не получаю никаких исключений. При отладке я вижу, что когда запрос на обработку возвращает false, так как не может найти цепочку правил (может быть, мне нужно как-то инициировать цепочку правил?).

Я предполагаю, что я что-то пропустил, чтобы переопределить, или моя инициализация неверна. У кого-нибудь есть опыт в этом? Можно ли вообще добиться правильного поведения?

Любая помощь приветствуется.


person vtor    schedule 13.03.2015    source источник


Ответы (2)


Так что, наконец, мне удалось получить эту работу.

Проблема заключалась в том, что добавления правил в 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();
    }

}

Тем не менее: Комментарии приветствуются.

person vtor    schedule 24.03.2015

В моем случае я хотел использовать значение свойства для построения правила. Я нашел более короткую версию, чтобы добиться того же, что и в сообщении выше.

@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);
  }
}
person Juan    schedule 12.03.2020