web-dev-qa-db-fra.com

Configurer la jetée intégrée avec web.xml?

J'essaie de générer à la fois une guerre avec mon application Web ainsi qu'un fichier jar autonome avec jetée intégrée. Pour la jetée intégrée (la distribution du fichier jar), j'ajoute un servlet comme suit:

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

La distribution des fichiers war utilise un fichier web.xml qui contient les éléments suivants dans la section 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>

Cela marche. Cependant, je veux me débarrasser de la duplication entre les deux approches. C'est-à-dire que lorsque j'ajoute un nouveau servlet, je veux avoir à le configurer dans un seul emplacement. Puis-je charger et utiliser le fichier web.xml à partir de la jetée intégrée?

27
Stephan

Utilisez un org.Eclipse.jetty.webapp.WebAppContext

Exemple:

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

Notez que vous allez créer un fichier WAR normal et l'utiliser avec Jetty.

Si vous avez des exigences particulières telles que la numérisation d'annotations ou JNDI, vous devrez entrer dans les spécifications de configuration.

// 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");

Pour un exemple plus long de cela dans un WebAppContext, voir l'exemple ServerWithAnnotations.

Notez également que vous aurez également toutes les règles du chargeur de classe webapp en utilisant cette technique. Cela signifie que vous aurez un chargeur de classe pour la webapp et un autre pour le serveur. C'est important à comprendre.

Il y a quelques modifications que vous pouvez apporter à WebAppContext pour les chargeurs de classe, mais vous ne pouvez pas les éliminer, il suffit de contrôler leur comportement.

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

Voir également:

18
Joakim Erdfelt

J'ai fini par utiliser l'approche de Joakim, mais en montrant le répertoire webapp au lieu du fichier 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();
}
17
Stephan