web-dev-qa-db-fra.com

L'annotation @WebServlet ne fonctionne pas avec Tomcat 8

Je souhaite utiliser l'annotation @WebServlet dans une application Web Java EE qui s'exécute sur Tomcat 8. 

J'ai lu que je devais déclarer la version 3.1 du servlet dans mon web.xml et que mon servlet devait étendre la HttpServlet. J'ai fait tout ça mais le @WebServlet ne fonctionne toujours pas. Je reçois un HTTP 404. 

J'ai également essayé ma configuration avec metadata-complete="false" dans mon web.xml, mais toujours sans succès.

Voici mon web.xml et Servlet. 

Vous trouverez le code complet complet sur GitHub .

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
  version="3.1" 
  xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

  <context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>true</param-value>
  </context-param>

  <!-- http://stackoverflow.com/a/7924117/451634 -->
  <!-- Put "-1" to disable this feature -->
  <context-param>
    <param-name>facelets.REFRESH_PERIOD</param-name>
    <param-value>1</param-value>
  </context-param>

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
  </welcome-file-list>

  <!-- JSF -->
  <listener>
    <listener-class>org.Apache.myfaces.webapp.StartupServletContextListener</listener-class>
  </listener>   

  <!-- CDI -->
  <listener>
    <listener-class>org.Apache.webbeans.servlet.WebBeansConfigurationListener</listener-class>
  </listener>

</web-app>

TestServlet.Java

import Java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "TestServlet", urlPatterns = {"*.serve"})
public class TestServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {
    try (ServletOutputStream out = resp.getOutputStream()) {
      out.write("Hello World".getBytes());
      out.flush();
    }
  }

}
13
Benny Neugebauer

Je l'ai fait travailler. J'ai dû étendre la façon dont j'ai démarré mon serveur Tomcat 8.0.12. 

Néanmoins, il y a trois choses principales à faire:

  1. web-app version dans web.xml doit être au moins égal à 3.0 ( j'ai utilisé 3.1 )
  2. metadata-complete dans web.xml peut ne pas être vrai (default is "false")
  3. Les répertoires classes doivent être ajoutés à Tomcat intégré avant de commencer.

Voici un exemple pour le fichier web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
  version="3.1" 
  metadata-complete="false"  
  xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

</web-app>

Voici à quoi ressemble ma classe principale Tomcat (qui prend désormais en charge les annotations @WebServlet):

public static void main(String[] args) throws Exception {
  String contextPath = "/";
  String webappDirLocation = "src/main/webapp/";
  String baseDirectory = new File(webappDirLocation).getAbsolutePath();

  Tomcat tomcat = new Tomcat();
  Tomcat.setPort(8080);
  StandardContext context = (StandardContext) Tomcat.addWebapp(contextPath, baseDirectory);

  // Additions to make @WebServlet work
  String buildPath = "target/classes";
  String webAppMount = "/WEB-INF/classes";

  File additionalWebInfClasses = new File(buildPath);
  WebResourceRoot resources = new StandardRoot(context);
  resources.addPreResources(new DirResourceSet(resources, webAppMount, additionalWebInfClasses.getAbsolutePath(), contextPath));
  context.setResources(resources);
  // End of additions

  Tomcat.start();
  Tomcat.getServer().await();
}
20
Benny Neugebauer

Que diriez-vous de @ServletComponentScan?

Exemple tiré de http://www.baeldung.com/spring-servletcomponentscan

@ServletComponentScan
@SpringBootApplication
public class SpringBootAnnotatedApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAnnotatedApp.class, args);
    }
}
0
Αλέκος

Essayez d'ajouter ceci:

((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true);
0
Magno C