从Java web项目构建WAR和可自行执行的JAR



我有一个Java servlet项目,我想构建一个WAR来部署到服务器和一个可执行的JAR,其中包含一个可以独立运行的嵌入式Jetty服务器。这个项目看起来是这样的:

HelloWorldServlets
common
src/main
java
HelloServlet.java
webapp
index.jsp
build.gradle
jetty
src/main
java
JettyServer.java
build.gradle
build.gradle

jetty导入common作为编译依赖项。构建任务是:

jar {
manifest { attributes "Main-Class": "JettyServer" }
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) })
}

common中的jar任务如下:

jar {
sourceSets.main.resources.srcDirs += ["src/main/webapp"]
}

web资源包括common.jarcommon.jarjetty.jar内部被扁平化,因此jetty.jar在其根目录中有资源,但将服务器设置为:

Server server = new Server(8080);
WebAppContext context = new WebAppContext();
server.setHandler(context);
context.setResourceBase("/");
context.setContextPath("/");
context.addServlet(Hello.class, "");

总是导致HTTP ERROR 404访问/index.jsp时出现问题。

我应该不将common.jar展平为jetty.jar,还是我缺少了ResourceBase的一些内容?谢谢

代码示例中的一些注意事项。

  • 由于您希望使用JSP,因此您必须满足JSP的最低要求
  • setResourceBase(String)必须是绝对路径和/或URI引用(没有相对路径((JSP要求(
  • 必须正确定义DefaultServlet。(JSP要求(
  • 添加Servlet(或过滤器(时,必须使用有效的url模式。(Servlet要求(
  • 在处理程序树中最后添加DefaultHandler,因为当您有上下文和/或处理程序错误需要解决时,它会有所帮助

出现问题的最常见原因是使用WebAppContext会强制执行标准Servlet类加载器隔离,并且很可能会导致出现问题。

要么破坏类加载器。。。

Server server = new Server(8080);
// Figure out what path to serve content from
ClassLoader cl = DemoProject.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("jsp-root/index.jsp");
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);
WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));
context.setContextPath("/");
context.addServlet(Hello.class, "/hello");
context.setParentLoaderPriority(true); // use server classloader first
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // for errors when request doesn't match above handlers
server.setHandler(handlers);

或者只是不使用WebAppContext。。。

Server server = new Server(8080);
// Figure out what path to serve content from
ClassLoader cl = DemoProject.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("jsp-root/index.jsp");
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();
context.setBaseResource(Resource.newResource(webRootUri));
context.setContextPath("/");
context.addServlet(Hello.class, "/hello");
// Must be added last, must be named "default" (JSP and Servlet requirement)
ServletHolder holderDef = new ServletHolder("default", DefaultServlet.class);
holderDef.setInitParameter("dirAllowed","false");
context.addServlet(holderDef,"/"); // Using "default" url-pattern (JSP and Servlet requirement)
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // for errors when request doesn't match above handlers
server.setHandler(handlers);

但是要注意,要在ServletContextHandler上启用JSP,您还有更多的工作要做。

有关详细信息,请参阅:https://github.com/jetty-project/embedded-jetty-jsp

最新更新