在Jetty中使用ResourceHandler和自定义处理程序时在根请求上获得403

在Jetty中使用ResourceHandler和自定义处理程序时在根请求上获得403,jetty,embedded-jetty,Jetty,Embedded Jetty,在(嵌入式)Jetty中,我尝试使用ResourceHandler为静态文件提供服务,并使用自定义处理程序响应动态请求。基于此,我有一个如下设置: public static void main(String[] args) throws Exception { Server server = new Server(); SelectChannelConnector connector = new SelectChannelConnector(); connector.s

在(嵌入式)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();
}
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;
}
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);
这在某种意义上是正确的:

  • 从我的公共目录中的文件提供静态内容,如/public/style.css
  • 在公共目录中不存在的路径上运行MyHandler,如/foo/bar
问题是我得到一个403作为根路径(/)的响应。MyHandler能够响应这些请求,但它们首先被ResourceHandler拦截。有没有办法强迫Jetty向MyHandler发送/请求


提前谢谢

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

我的解决方案是颠倒列出处理程序的顺序,以便首先调用您的处理程序。然后检查URL中的特殊情况“/”。如果希望将请求传递给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();
}
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;
}
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);
并定义CustomHandler的句柄方法,如下所示:

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();
}
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;
}
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);
我同意让ResourceHandler简单地在“/”上屈服,而不是用403来处理响应,这将是最优雅的做法。

我的解决方案:

  • 将MyHandler置于与“/”不同的上下文路径上,例如“/index”
  • 使用重写规则拦截对“/”的调用并将其重定向到“/索引”
我使用的代码如下所示:

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();
}
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;
}
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);
正则表达式确保只匹配精确的路径,因此“无论什么”仍然首先由ResourceHandler处理。

非常感谢:)我正在开发一个可重用的插件,用于使用Gradle创建基于战争的Web应用程序的开发环境,并最终实现了一个类似于您在这里描述的解决方案。