Java 使用 web.xml 配置嵌入式码头?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20786661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Configure embedded jetty with web.xml?
提问by Stephan
I am trying to generate both a war with my web application as well as a self contained jar file with embedded jetty. For the embedded jetty (the jar file distribution) I add a servlet as follows:
我试图生成与我的 Web 应用程序的战争以及带有嵌入式码头的自包含 jar 文件。对于嵌入式码头(jar 文件分发),我添加了一个 servlet,如下所示:
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
context.addServlet(new ServletHolder(new HelloServlet()),"/*");
server.start();
server.join();
}
The war file distribution uses a web.xml file that contains the following in the web-app section:
war 文件分发使用 web.xml 文件,该文件在 web-app 部分包含以下内容:
<servlet>
<servlet-class>com.example.HelloServlet</servlet-class>
<servlet-name>SimplestServer</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This works. However, I want to get rid of the duplication between the two approaches. I.e., when I add a new servlet I want to have to configure it in only one location. Can I load and use the web.xml file from the embedded jetty?
这有效。但是,我想摆脱两种方法之间的重复。即,当我添加一个新的 servlet 时,我只想在一个位置配置它。我可以从嵌入式码头加载和使用 web.xml 文件吗?
采纳答案by Joakim Erdfelt
Use a org.eclipse.jetty.webapp.WebAppContext
用一个 org.eclipse.jetty.webapp.WebAppContext
Example:
例子:
package jetty;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
public class OnWebApp
{
public static void main(String[] args) throws Exception
{
// Create a basic jetty server object that will listen on port 8080.
// Note that if you set this to port 0 then a randomly available port
// will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server = new Server(8080);
// The WebAppContext is the entity that controls the environment in
// which a web application lives and breathes. In this example the
// context path is being set to "/" so it is suitable for serving
// root context requests and then we see it setting the location of
// the war. A whole host of other configurations are available,
// ranging from configuring to support annotation scanning in the
// webapp (through PlusConfiguration) to choosing where the webapp
// will unpack itself.
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar("path/to/my/test.war");
// A WebAppContext is a ContextHandler as well so it needs to be set to
// the server so it is aware of where to send the appropriate requests.
server.setHandler(webapp);
// Start things up! By using the server.join() the server thread will
// join with the current thread.
// See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()
// for more details.
server.start();
server.join();
}
}
Note that you will build a normal WAR file, and use it with Jetty.
请注意,您将构建一个普通的 WAR 文件,并将其与 Jetty 一起使用。
If you have special requirements such as Annotation scanning or JNDI, then you'll need to get into configuration specification.
如果您有特殊要求,例如注释扫描或 JNDI,那么您需要进入配置规范。
// Enable parsing of jndi-related parts of web.xml and jetty-env.xml
org.eclipse.jetty.webapp.Configuration.ClassList classlist =
org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
// Enable JNDI
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
"org.eclipse.jetty.plus.webapp.PlusConfiguration");
// Enable Annotation Scanning
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
For a longer example of this in a WebAppContext, see the ServerWithAnnotations example.
有关 WebAppContext 中的更长示例,请参阅 ServerWithAnnotations 示例。
Also note that you will have all of the webapp classloader rules in place using this technique as well. Meaning you will have a classloader for the webapp and another one for the server. This is important to understand.
另请注意,您还将使用此技术设置所有 webapp 类加载器规则。这意味着您将有一个用于 web 应用程序的类加载器和另一个用于服务器的类加载器。理解这一点很重要。
There are a few tweaks you can do to the WebAppContext for classloaders, but you can't eliminate them, just control how they behave.
您可以对类加载器的 WebAppContext 进行一些调整,但无法消除它们,只能控制它们的行为方式。
WebAppContext webapp = new WebAppContext();
// ... various setup of the webapp ...
// Flip the classloader priority from servlet spec where webapp is first to
// Standard java behavior of parent (aka Server classloader) is first.
webapp.setParentLoaderPriority(true);
See also:
也可以看看:
回答by Stephan
I ended up using Joakim's approach, but pointing at the webapp directory instead of the war file.
我最终使用了 Joakim 的方法,但指向 webapp 目录而不是 war 文件。
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
String rootPath = SimplestServer.class.getClassLoader().getResource(".").toString();
WebAppContext webapp = new WebAppContext(rootPath + "../../src/main/webapp", "");
server.setHandler(webapp);
server.start();
server.join();
}