带有爆炸战的嵌入式Jetty,使用带注释的配置

时间:2016-05-29 20:51:02

标签: java servlets embedded-jetty

我正在学习Java EE 7 Servlets并尝试使用嵌入式Jetty(v 9.3.7)从Java EE 7教程部署hello2 example,但收效甚微。 hello2由两个servlet和一个图像文件组成。配置已注释,项目没有任何web.xml。

在嵌入式Jetty examplesWebAppContext部分之后,我创建了这个主类来启动我的嵌入式服务器:

public class MyServer {

public static void main(String[] args) throws Exception {
    Server server = new Server(8080);
    String webappPath = new File(MyServer.class.getProtectionDomain().getCodeSource().getLocation().getFile())
                .getParentFile().getParentFile().getAbsolutePath();

    WebAppContext webapp = new WebAppContext(webappPath, "");

    webapp.setConfigurations(new Configuration[]{
            new AnnotationConfiguration()});

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

据我所知,由于Jetty是一个Java EE Web容器,它应该能够按原样提供示例Serlvet项目,我只需要指向war文件夹结构。以下是项目的结构:

-- hello2
\-- src
    \-- main
        +-- java
        │   +-- MyServer.java
        │   \-- javaeetutorial
        │       \-- hello2
        │           +-- GreetingServlet.java
        │           \-- ResponseServlet.java
        \-- webapp
            +-- WEB-INF
            │   \-- classes
            │       +-- MyServer.class
            │       \-- javaeetutorial
            │           \-- hello2
            │               +-- GreetingServlet.class
            │               \-- ResponseServlet.class
            +-- index.html
            \-- resources
                \-- images
                    \-- duke.waving.gif

可以找到hello2示例代码here。以下是GreetingServlet

的部分内容
@WebServlet("/greeting")
public class GreetingServlet extends HttpServlet {

@Override
public void doGet(HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
....

ResponseServlet

@WebServlet("/response")
public class ResponseServlet extends HttpServlet {

@Override
public void doGet(HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
....

文件被编译为hello2/webapp/classes/,从而使webapp文件夹成为爆炸的WAR。 index.html是我添加的,只是为了测试Jetty是否选择了它。结果是当我访问localhost时出现错误404:8080,localhost:8080 / greeting或localhost:8080 / response

如果我使用WebXmlConfiguration添加webapp.setConfigurations(),然后像webapp.setResourceBase(webappPath)那样设置资源库,我就会设法进入Jetty的静态文件服务器。这是因为Jetty然后使用默认的web.xml,它将自己的servlet添加到服务器以用于文件服务。但即便如此,我的注释servlet也没有被选中。

我让Jetty读取带注释的servlet配置的方法是使用WEB-INF显式设置WebAppContext.getMetadata().setWebInfClassesDirs()目录:

webapp.getMetaData().setWebInfClassesDirs(
  Arrays.asList(Resource.newResource(
    MyServer.class.getProtectionDomain().getCodeSource().getLocation())));

然后,servlet按预期响应,但这不会为我的index.html或图像文件提供服务。我还将资源库设置为无用。所以我想要的是Jetty在没有web.xml的情况下为我的Web应用程序提供服务,只需将其指向爆炸的WAR目录即可。显然我错过了一些东西。

2 个答案:

答案 0 :(得分:0)

使用......

webapp.setConfigurations(new Configuration[]{
        new AnnotationConfiguration()});

将撤消所有现有重要配置,并且仅启用AnnotationConfiguration

难怪它不适合您,使用该设置,缺少加载WEB-INF/web.xml的配置,缺少使用WEB-INF/lib的配置等。

你必须适当地修改现有的配置列表,并且有很多例子可以向你展示。

由于您没有指定是否有使用JNDI的注释,或存在于Web片段中,或者来自webapp上下文之外(例如容器本身),因此您需要的确切配置很难指定。

请参阅https://github.com/jetty-project/embedded-servlet-3.1项目以获取执行此操作的完整项目。

context.setConfigurations(new Configuration[] 
    { 
        new AnnotationConfiguration(),
        new WebInfConfiguration(), 
        new WebXmlConfiguration(),
        new MetaInfConfiguration(), 
        new FragmentConfiguration(), 
        new EnvConfiguration(),
        new PlusConfiguration(), 
        new JettyWebXmlConfiguration() 
    });

这是一种常规设置,这是最常见的设置,但可能会让您接触到您可能不需要的额外配置。

即使您不想要其他组件,您仍然需要将它们留给已发现的Web应用程序。否则,您有一个100%的手动网络应用程序,您可以专门致电.addServlet().addFilter()等。

您应该使用此语法。

private void enableAnnotationScanning(Server server)
{
    Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
    classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
            "org.eclipse.jetty.annotations.AnnotationConfiguration");
}

因为这会修改现有的配置列表,只需添加AnnotationConfiguration

如果您想查看此格式的其他示例,请查看以下示例项目:

答案 1 :(得分:0)

在与Joakim Erdfelt讨论后,我进一步研究了Tomcat,我知道Jetty可能不是测试不同类型的Java EE Web功能的最佳容器。 Jetty以其他方式实现了对Java EE的支持,而Glasshfish和Tomcat则需要不同的设置方法,这在Joakims回答的讨论中有详细阐述。

使用以下代码段使用Tomcat进行测试后

public class MyServer {

public static void main(String[] args) throws Exception {
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(8080);

    tomcat.addWebapp("","webapp"); 

    tomcat.start();
    tomcat.getServer().await();
    }

 }

它首先看起来像Tomcat不需要任何web.xml,但在进一步调查之后,Tomcat使用默认的web.xml(如果没有提供)。此web.xml包含<welcome-file>index.html</welcome-file>DefaultServlet,用于提供静态内容。这种方法与Jettys类似,我认为这也是Glassfish的工作原理。所吸取的经验教训是,总有某种类型的DefaultServlet潜伏在Java EE Web服务器的后台,它可以完成一些神奇的工作。即使web.xml对于服务器的用户是可选的,服务器仍然在幕后提供它以使其自己工作。