【问题标题】:How to get embedded Jetty serving html files from a Jar, not a War如何从 Jar 而不是 War 中获取嵌入式 Jetty 服务 html 文件
【发布时间】:2016-02-23 02:40:30
【问题描述】:

我一直在寻找如何让嵌入式码头服务器为同一个 jar 中包含的少量 html 文件提供服务,但没有成功。这肯定是可能的吗?

如果没有必要,我真的不想经历建造和打仗的麻烦。理想情况下,我也不必创建 WEB-INFO 目录和 web.xml 文件,尽管我读过的所有解决方案似乎都指向这样做并使用 WebAppContext。

我已阅读以下链接,但没有找到从 jar 运行时设置 ResourceBase 或 BaseResource 属性的方法。

Start java application with jetty without WAR file

What is correct URL to specify ResourceBase of JAR "resources/webapp" folder for embedded Jetty?

Embedded Jetty looking for files inside its Jar file

在 DEV 期间通过 IDE 运行很简单,代码工作正常,看起来像这样..

Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(httpPort);
server.addConnector(connector);

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setWelcomeFiles(new String[]{"welcome.html"});
server.setHandler(context);

ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
holderPwd.setInitParameter("resourceBase","./Relative/Path/To/Html/Files");
holderPwd.setInitParameter("dirAllowed","true");
context.addServlet(holderPwd,"/");

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

那么,我必须使用 WebAppContext 而不是 ServletContextHandler 吗?如果是,那么我是否也必须添加 webapp/WEB-INFO/web.xml 目录结构?而且如果我这样做了,那我是不是必须打包成战争?

【问题讨论】:

  • 我没有看到来自3rd questionsetResourceBase 呼叫;应该这样做。或者您可以指定您自己的 servlet 实现并使用 ClassLoader.getResource()
  • 肯尼 - 我以为我是通过以下方式做到这一点的? holderPwd.setInitParameter("resourceBase",...)
  • 你可能是对的。您是否尝试过将 this.class.getClassLoader().getResource("com/company/project/mywebdir").toExternalForm(); 之类的内容作为第二个参数传递?你得到了什么结果,404?
  • Kenney,externalForm() 提供了一个路径,但不幸的是它只会导致 404s

标签: java html jar jetty


【解决方案1】:

您需要将 Context 的 Resource Base 设置为可以从中访问静态内容的 URL/URI。

注意:您将其设置在ServletContext 级别,而不是DefaultServlet 级别,这样您上下文中的所有servlet 都可以访问相同的信息以及ServletContext 中与真实文件路径和资源相关的各种方法是理智的。

public static void main(String[] args) throws Exception
{
    Server server = new Server(8080);

    // Figure out what path to serve content from
    ClassLoader cl = MyEmbeddedJettyMain.class.getClassLoader();
    // We look for a file, as ClassLoader.getResource() is not
    // designed to look for directories (we resolve the directory later)
    URL f = cl.getResource("static-root/hello.html");
    if (f == null)
    {
        throw new RuntimeException("Unable to find resource directory");
    }

    // Resolve file to directory
    URI webRootUri = f.toURI().resolve("./").normalize();
    System.err.println("WebRoot is " + webRootUri);

    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    context.setBaseResource(Resource.newResource(webRootUri));
    context.setWelcomeFiles(new String[]{"welcome.html"});

    ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
    holderPwd.setInitParameter("dirAllowed","true");
    context.addServlet(holderPwd,"/");

    server.setHandler(context);

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

【讨论】:

  • 感谢 Joakim,它在 IDE 中运行良好,但在 Jar 中执行 url.toURI() 步骤时会引发错误。 “java.lang.IllegalArgumentException:URI 不是绝对的”。 url的路径是这样的.."file:/C:/dev/Project/Namespace/target/ComponentName-dev-SNAPSHOT-dist/lib/ComponentName-dev-SNAPSHOT.jar!/charts/welcome.html "
  • 好的,谢谢。在您的帮助下解决了它,并在我认为您发布的 github 上找到了该项目。 github.com/jetty-project/embedded-jetty-uber-jar.. 我的 html 文件没有放在资源目录下,这就是问题所在。
  • 是否有机会通过 web.xml 为非嵌入式 Jetty 从任意 JAR 配置静态资源?
  • @GullerYA web.xml 用于正式的 webapp(又名 servlet 规范),因此没有任意资源位置。但你可以使用 WEB-INF/lib/*.jar!META-INF/resources(又名 servlet web 资源 jars)
  • 感谢您的快速回答,首先。它不是那样工作的,Jetty 抛出“no!/ in spec”异常。我试图替换“!”使用“!/”,但它仍然是 404,这看起来是正确的,因为 jar 在 META-INF 中没有资源,资源位于 JAR 的根目录中的上一层...
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
相关资源
最近更新 更多