2016-05-29 63 views
0

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

WebAppContext部分从嵌入码头examples我创造了这个主类以启动我的嵌入式服务器:

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(); 
    } 
} 

据我了解,由于码头是一个Java EE Web容器,它应该能够服务于示例Serlvet项目是,我只需要指向战争文件夹结构。以下是该项目的结构:

-- 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。以下是该文件被编译为hello2/webapp/classes/从而使webapp文件夹的分解WAR的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 { 
.... 

某些部分。我添加index.html是为了测试Jetty是否选择它。其结果是,我得到404错误当我访问本地主机:8080,本地主机:8080 /问候或本地主机:8080 /响应

如果我添加WebXmlConfigurationwebapp.setConfigurations(),然后设置类似webapp.setResourceBase(webappPath)的资源基础,我设法进入Jetty的静态文件服务器。这是因为Jetty然后使用默认的web.xml,它将用于文件服务目的的servlet添加到服务器。但即使如此,我的注释servlet没有拿起。

我有码头阅读注释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目录即可。显然我错过了一些东西。

回答

0

使用...

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

将取消所有现存的重要配置,只启用了AnnotationConfiguration

难怪它不为你工作,与安装,加载WEB-INF/web.xml缺少的配置,使用WEB-INF/lib配置丢失等

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

由于您没有指定使用JNDI的注释,或者存在于web-fragments中,或者来自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%的手动Web应用程序,你特别呼吁.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

如果你想看到这种格式的其他例子,看看下面的示例项目:

+0

正如我在我的问题中写的,我使用注释来配置,而不是在Java EE 7中可选的web.xml。另外,我相信我不需要WEB-INF/lib,因为我没有使用它。我只使用了AnnotationConfiguration,因为我配置了注释中的所有内容,我想了解它为什么不起作用。我的理论是,这个设置应该适用于所有支持servlet容器的Java EE 7。 – qtips

+0

即使您没有实际的文件,您仍然需要配置,因为这是如何设置webapp元数据的。没有配置,没有元数据,没有关于设置的知识,等等。元数据是构建在所有这些配置上的。只有Annotation/Plus/Env是可选的,其余都是必需的。 –

+0

添加WebInfConfiguration时,Jetty开始阅读我的注释配置:)我仍然认为我不应该需要WebXmlConfiguration,因为我看到Jetty使用默认的web.xml来设置一些内置的servlet。但没有它,Jetty不会服务我的index.html。为什么必须添加自己的web.xml以支持静态内容?我想我被Jettys WebAppContext弄糊涂了;它用于专门为Web应用程序提供服务(与ServletContextHandler相比),但不支持标准的Java EE配置,不使用setConfigurations。 – qtips

0

与乔金 - Erdfelt讨论之后,我再看着Tomcat和我明白,码头可能不是测试不同种类的Java EE Web功能的最佳容器。 Jetty以其他方式实现对Java EE的支持,而不是Glasshfish和Tomcat,而这又需要不同的设置方法,这在Joakims答案下的讨论中进行了详细说明。

使用下面的代码片断

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和Tomcat测试如果不能提供一个后。这个web.xml包含一个<welcome-file>index.html</welcome-file>和一个提供静态内容的DefaultServlet。这种方法与Jettys类似,我认为这也是Glassfish的工作原理。所以经验教训是,总是有一些DefaultServlet潜伏在Java EE web服务器的后台,这有一些神奇的功能。即使web.xml对服务器的用户是可选的,服务器仍然在幕后提供它以使其自行工作。

+0

对我所说的有趣的解释。 :-( –

+0

如果我误解了你,我很抱歉:(jetty似乎非常灵活,可能也提供了更好的性能,但是这种灵活性使得安装更加困难,你不能简单地遵循官方的Java EE教程设置并期望它能够工作。你必须添加码头特定的设置才能使其工作。当然这不是一个大问题,但是在学习Java EE和Sevlet时可能会有点混淆。 – qtips

+0

如果你专注于Java EE,我会推荐使用[TomEE](http://tomee.apache.org/),而不是普通的Tomcat(因为它与Jetty的子集范围相同)。但是请注意,TomEE并不擅长嵌入(主要是由于Java EE对它的限制) –

相关问题