4

在(嵌入式)Jetty 中,我试图使用 ResourceHandler 来提供静态文件和自定义处理程序来响应动态请求。基于此页面,我有一个如下所示的设置:

public static void main(String[] args) throws Exception
{
    Server server = new Server();
    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(8080);
    server.addConnector(connector);

    ResourceHandler resource_handler = new ResourceHandler();
    resource_handler.setDirectoriesListed(false);

    resource_handler.setResourceBase(".");

    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { resource_handler, new MyHandler() });
    server.setHandler(handlers);

    server.start();
    server.join();
}

这在正确的意义上是有效的:

  • 从我的公共目录中的文件中提供静态内容,例如 /public/style.css
  • 在公共目录中不存在的路径上运行 MyHandler,例如 /foo/bar

问题是我得到一个 403 响应根路径 (/)。MyHandler 能够响应这些请求,但它们首先被 ResourceHandler 拦截。有什么方法可以强制 Jetty 向 MyHandler 发送/请求?

提前致谢!

4

2 回答 2

3

Jetty 按顺序尝试每个处理程序,直到其中一个处理程序在请求上调用 setHandled(true)。不知道为什么 ResourceHandler 不对“/”执行此操作。

我的解决方案是颠倒您列出处理程序的顺序,以便首先调用您的处理程序。然后检查 URL 中的特殊情况“/”。如果您想将请求传递给 ResourceHandler,只需返回而不声明请求已处理。

像这样声明处理程序的顺序:

Server server = new Server(8080);

CustomHandler default = new CustomHandler();
default.setServer(server);

ResourceHandler files = new ResourceHandler();
files.setServer(server);
files.setResourceBase("./path/to/resources");

HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] {default, files});

server.setHandler(handlers);

server.start();
server.join();

并像这样定义CustomHandler的handle方法:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
    if(!request.getRequestURI().equals("/")){
        return;
    }
    // Do Stuff...
    baseRequest.setHandled(true);
    return;
}

我同意让 ResourceHandler 简单地在“/”上屈服而不是用 403 处理响应是最优雅的。

于 2013-03-30T22:15:06.767 回答
2

我的解决方案:

  • 将 MyHandler 放在与“/”不同的上下文路径上,例如“/index”
  • 使用重写规则拦截对“/”的调用并将它们重定向到“/index”

我使用的代码如下所示:

RewriteHandler rewriteHandler = new RewriteHandler();
rewriteHandler.setRewriteRequestURI(true);
rewriteHandler.setRewritePathInfo(false);
rewriteHandler.setOriginalPathAttribute("requestedPath");
RewriteRegexRule rewriteIndex = new RewriteRegexRule();
rewriteIndex.setRegex("^/$");
rewriteIndex.setReplacement("/index.html");
rewriteHandler.addRule(rewriteIndex);
rewriteHandler.setHandler(rootHandlerCollection);
server.setHandler(rewriteHandler);

正则表达式确保只匹配确切的路径,因此“/whatever”仍然首先由 ResourceHandler 处理。

于 2014-08-20T13:22:46.513 回答