gpt4 book ai didi

java - jetty 9 : How to organise handlers & setWelcomeFiles

转载 作者:行者123 更新时间:2023-11-30 03:37:38 24 4
gpt4 key购买 nike

我正在使用嵌入式 Jetty 9,其中 Jetty 是我的应用程序的一个小角落。我混合了静态内容、servlet 和 jsp。我的 servlet 和 jsp 是我的源代码树的一部分,并进入可执行 jar 并遵循正常的包结构。也许我的一些静态内容会在jar中,但其他静态内容,包括index.html应该放在项目根文件夹中;它可以作为网页内容位于子文件夹中。我的 servlet 和 jsp 被编译到 bin 类树中的某个位置。

我创建了一个 HandlerList,其中包含 servletContext(servlet)、resource_handler(static content)、webAppContext(jsp) 和 DefaultHandler。我的resource_handler 将WelcomeFiles 设置为“index.html”,将ResourceBase 设置为“./web-content”。

我尝试过 HandlerList 的不同顺序。如果我把resource_handler放在第一位,然后主页工作正常,但是resource_handler可以吃掉其他文件。如果我把resource_handler放在最后,那么主页就会得到404。

列表中的第一个工作正常,但当它是第二个或第三个时我会遇到问题。

我知道每个处理程序都会尝试处理上下文路径,如果不能,则将其传递给下一个处理程序。我不太清楚下一个处理程序开始的上下文路径。它是否转到基本上下文/或者是否从前一个处理程序停止的地方继续。为什么它看不到我的index.html?

我希望能够将内容、静态、servlet 或 jsp(几乎)放在我想要的任何地方,并选择上下文路径以在浏览器和具有/上下文的主页上看起来合乎逻辑。然后让服务器找到它。

这是嵌入的,因此我不需要遵守 war 规则。

组织/排序处理程序 - 上下文 -welcomeFiles 的规则是什么?

最佳答案

我正在制定一些规则来回答我的问题,主要是通过实验。

1.当将 ResourceHandler 用于静态内容时,不要使用 setContextPath("/"),因为它会匹配太多。

2.对于每个上下文路径,使用不同的路径,例如,对于 ResourceHandler(1) 使用(例如)/static1,对于 ResourceHandler(2) 使用/static2,对于 servlet 使用/servlet。因为没有“/”路径,所以每个路径都可以轻松映射到它应该提供的服务。

3.不使用 。或 * 在 ResourceHandler 上下文路径上,只是/foo 而不是/foo/* 或 ./foo

4.在 servlet 路径上,请使用 * 来表示路径信息,例如使用/servlet/*。然后在servlet中使用request.getPathInfo()来对*.
中的内容进行排序

5.对于 setWelcomeFiles 只需使用“index.html”。按照 6 中的方式完成路径的其余部分。

6.将index.html放在/web(src旁边)中,然后对于相应的ResourceHandler,setResourceBase =“web”(无斜杠=相对路径)。那么它(很容易)不在可运行的 jar 中

6a。如果您希望将其放入 jar 中,请将其放入 Main.java 旁边的/resources 包中,然后 Eclipse 导出将打包该 jar,而无需求助于 Ant。 (可能需要在这里摆弄 loadResource() ?

7.将 ResourceHandler 分组到 ContextHandlerCollection 中,因为“它基于上下文路径创建一个包含处理程序的 PathMap ”,然后将它们包含在下面的 8 中。

8.使用 HandlerCollection 来收集 Servlet,因为“它会按列表顺序调用所有处理程序,无论响应状态或异常如何”。确实包括 7 个集合。

9.请注意,在index.html 中,路径可以相对于为index.html 提供服务的ResourceHandler 设置的上下文路径,在此示例中为/static1。因此,使用 Servlet 的绝对链接就像 href="/servlet/help"一样,在浏览器中为 localhost:80/servlet/help。 (或在相对路径上构建方案)

这就是我所掌握的。但事情正在开始发挥作用。我正在使用没有 xml 配置的嵌入式 jetty。我还没有将我的 jsp 与此合并,但我希望我现在有足够的“规则”来做到这一点。

如果专家能够评论或扩展/简化这​​些经验规则,那就太好了!

(编辑)

为什么会发生这种情况?

当我使用第二个 ResourceHandler 时,它可以正常提供内容(如在浏览器上看到的那样),但随后给出 IllegalStateException。为了查看发生了什么,我重写了 ResourceHandler.handle 方法,并仅使用 super.handle() 记录请求和 isCooperative()。 isCommited() 显示 true。但是,从句柄返回时,我看到日志消息:

INFO WebServer.configureResourceHandler(2)  target=/foo/bar.bar  request url=http:\\192.168.2.106:8080/static2/foo/bar.bar,  isCommitted=true
WARNING ###### org.eclipse.jetty.server.Response.Committed before 404 null
WARNING ###### org.eclipse.jetty.servlet.ServletHandler./static2/foo/bar.bar
WARNING ###### org.eclipse.jetty.server.HttpChannel./static2/foo/bar.bar
WARNING ###### org.eclipse.jetty.server.HttpChannel.Could not send response error 500: java.lang.IllegalStateException: Committed

看起来ResourceHandler.handle()方法已经提供了内容ok(根据浏览器)并设置了isCooperative true,但是handle()之后的代码不知道它已经被处理了,想要执行 404 但不能,因此记录 500(它无法发送,因为响应已提交)。

我做错了什么还是这是一个错误?

回答

不是错误。我将 ContextHandlerCollection 项目与 HandlerCollection 项目混合在一起。前者由上下文路径过滤,后者则不然。所以我的 servlet 试图处理已经处理过的项目。通过以与静态内容相同的方式处理 servlet 来解决此问题。使用这样的代码:

private ContextHandler configureRootServlet() {
ServletContextHandler context = new ServletContextHandler(); /* Can hold several servlets */
context.setContextPath( "/servlet" );
ServletHandler handler = new ServletHandler();
context.setHandler( handler );
handler.addServletWithMapping( RootServlet.class, "/*");
rootServlet = (RootServlet)handler.getServlets()[0].getServlet();/*We
only added one. Grab the servlet instance he created for us so we can
configure it */
// Configure the servlet
rootServlet.setMain( mainClass );
// etc
return context;
}

然后只需将 ServletContextHandler 添加到 ContextHandlerCollection 即可。请注意,Servlet 映射是相对于上下文的。将它们全部包裹在一起......

ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[]{ configureResourceHandler1()
, configureResourceHandler2(), configureRootServletHandler() });
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers( new Handler[]{ contexts, new DefaultHandler()
,configureRequestLogHandler() });

现在没有服务器错误!

关于java - jetty 9 : How to organise handlers & setWelcomeFiles,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27475536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com