在 Jetty 中将 web.xml 与 WebAppContext 结合使用

Using web.xml with WebAppContext in Jetty

这是我的第一个 Web 应用程序,我只是想按照指南并使用在 web.xml 指定的 servlets 启动我的服务器,但似乎我的操作不正确'更改服务器的功能,结果是 404 错误。但是,如果我以编程方式指定 servlet 就可以了。谁能弄清楚这一切应该如何运作? 这是我的服务器代码

public class Launcher
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
        WebAppContext web = new WebAppContext();
        web.setContextPath("/");
        web.setWar("src/main/web/WEB-INF/web.xml");
        //web.addServlet(MyServlet.class,"/"); This line works just fine
        server.setHandler(web);
        server.start();
        server.join();
    }
}

我的 web.xml 看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>lab3.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>*</url-pattern>
    </servlet-mapping>
</web-app>

WEB-INF/web.xml是描述符。

WebAppContext.setWar(String) 的调用用于基本资源位置。

Note: The Base Resource location is mandatory. You must set it to a valid location so that the ServletContext can function properly.

There are alternate APIs for setting the base resource location: you can use WebAppContext.setBaseResource(Resource) and WebAppContext.setResourceBase(String) as well, they mean the same thing.

如果要指定 Web 描述符位置,请使用 WebAppContext.setDescriptor(String)

对于您的代码示例,您似乎想使用

    Server server = new Server(8080);
    WebAppContext web = new WebAppContext();
    web.setContextPath("/");
    web.setWar("src/main/web"); // TODO: resolve this to a an absolute path or URI!
    server.setHandler(web);
    server.start();
    server.join();

关于该 TODO,请参阅 jetty-project/embedded-jetty-cookbook 中的示例,具体...

重要的是要认识到,默认情况下,类路径将基于基本资源位置。

将从 ${base.resource.uri}/classes 中查找 类。

我指出这一点,因为我们在您的示例中看到了路径 src/main/web,我怀疑您正试图在 IDE 工作中创建一个实时(未构建)项目。这种设置将需要您进行更多手动操作,因为基础资源和 类 位于不同的位置。

在这种情况下,您需要手动指定 类 的位置。

又名

    Server server = new Server(8080);
    WebAppContext web = new WebAppContext();
    web.setContextPath("/");

    Path baseResource = new File("src/main/web").toPath();
    Path classesDir = new File("target/thewebapp/WEB-INF/classes").toPath();

    if (!Files.exists(baseResource))
        throw new FileNotFoundException("Unable to find Base Resource Dir: " + baseResource);
    if (!Files.exists(classesDir))
        throw new FileNotFoundException("Unable to find Classes Dir: " + classesDir);

    web.setBaseResource(new PathResource(baseResource.toAbsolutePath()));
    web.setExtraClasspath(classesDir.toAbsolutePath().toString());
    server.setHandler(web);
    server.start();
    server.join();

最后我想指出一些其他的方法,你可以在 embedded-jetty 中打包 webapp ...

embedded-jetty-uber-jar

https://github.com/jetty-project/embedded-jetty-uber-jar

这里使用ServletContextHandler手动构建webapp,没有使用WEB-INF/web.xml,没有字节码扫描,没有注解扫描,启动速度快得惊人。

以上项目构建了一个 jar,其中包含 运行 您的 webapp 所需的一切。

embedded-jetty-直播-war

https://github.com/jetty-project/embedded-jetty-live-war

这个项目有点复杂,它构建了 3 个部分(webapp、服务器、bootstrap),然后将它们组装成一个 war 文件。

这从一个简单的 war 开始,然后使用按照您想要的方式预先配置的服务器对其进行增强。这个新的 "live-war" 被组装成一个新的 war 文件在单独的 sub-project.

这个war文件可以正常部署,可以运行直接作为独立的self-executingwar 文件,完整的服务器实例。