在(嵌入式)码头中,我正在尝试使用资源处理程序来提供静态文件,并使用自定义处理程序来响应动态请求。基于此页面,我有一个如下所示的设置:
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"仍然首先由资源处理程序处理。