在 Jetty 中使用资源处理程序和自定义处理程序时,在根请求上获取 403



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

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发送/请求?

提前感谢!

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

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

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

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

并像这样定义自定义处理程序的句柄方法:

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

我同意让资源处理程序简单地屈服于"/"而不是使用 403 处理响应是最优雅的。

我的解决方案:

  • 将 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"仍然首先由资源处理程序处理。

最新更新