Встроенная перезапись Jetty не работает должным образом

Я пытаюсь реализовать простое правило перезаписи на встроенном сервере Jetty, следуя примерам документации Jetty.

Я хочу, чтобы запросы к /admin/ переписывались в /admin.html. На данный момент, если я запрашиваю /admin/, я получаю ошибку 404 с /admin.html не найденным. Но если я запрошу /admin.html напрямую, это сработает!

В stackoverflow есть еще 2 похожих сообщения, но нет ответов на вопрос!

Вот код:

WebAppContext _ctx = new WebAppContext();
_ctx.setContextPath("/");
_ctx.setDefaultsDescriptor(JETTY_DEFAULTS_DESCRIPTOR);
_ctx.setParentLoaderPriority(true);       
_ctx.setWar(getShadedWarUrl());
_ctx.setResourceBase(getShadedWarUrl());

RewriteHandler rewriter = new RewriteHandler();
rewriter.setRewritePathInfo(true);
rewriter.setRewriteRequestURI(true);
rewriter.setOriginalPathAttribute("requestedPath");

RewritePatternRule admin = new RewritePatternRule();
admin.setPattern("/admin/");
admin.setReplacement("/admin.html");
admin.setTerminating(true); // this will stop Jetty from chaining the rewrites
rewriter.addRule(admin);

_ctx.setHandler(rewriter);

HandlerCollection _handlerCollection = new HandlerCollection();
_handlerCollection.setHandlers(new Handler[] {_ctx});
server.setHandlers(_result);

person Melissa    schedule 21.01.2013    source источник


Ответы (1)


Замените 2 строки...

_ctx.setHandler(rewriter);
_handlerCollection.setHandlers(new Handler[] {_ctx});

с участием

rewriter.setHandler(_ctx);
_handlerCollection.setHandlers(new Handler[] {rewriter});

Это приведет к тому, что правила переписывания сработают перед обычной обработкой контекста.

Думайте об обработке контекста как о дереве. В вашем примере кода у вас есть ....

server
+--  HandlerCollection
     [0]-- WebAppContext
           +-- Your servlets and filters in web.xml
           +-- DefaultServlet
               +-- RewriteHandler

Это означает, что если WebAppContext не может обработать запрос, то выполняется RewriteHandler, чтобы проверить, может ли он обработать запрос. Этого никогда не произойдет, так как WebAppContext настроен на использование DefaultServlet, если ничего не совпадает.

Предлагаемое простое изменение изменяет дерево, чтобы оно выглядело так...

server
+--  HandlerCollection
     [0]-- RewriteHandler
           +-- WebAppContext
               +-- Your servlets and filters in web.xml
               +-- DefaultServlet

Это позволит RewriteHandler сделать свое дело еще до того, как WebAppContext спросят.

Примечание: вы также можете сделать так, чтобы ваш код использовал HandlerCollection немного более правильно для этого сценария.

// _ctx.setHandler(rewriter);
// rewriter.setHandler(_ctx);
_handlerCollection.setHandlers(new Handler[] { rewriter, _ctx });

Это приведет к следующему дереву

server
+--  HandlerCollection
     [0]-- RewriteHandler
     [1]-- WebAppContext
           +-- Your servlets and filters in web.xml
           +-- DefaultServlet
person Community    schedule 22.01.2013
comment
Это очень полезно! Спасибо! - person Melissa; 23.01.2013