2014-09-28 72 views
9

工作,我想用@WebServlet标注在它运行在Tomcat 8@WebServlet标注不使用Tomcat 8

我已阅读,我需要声明的Servlet 3.1版在我web.xml和Java EE Web应用程序我的Servlet需要扩展HttpServlet。我做了所有这些但仍然@WebServlet不起作用。我得到一个HTTP 404.

我也试过我的配置metadata-complete="false"在我的web.xml,但仍然没有成功。

这是我的web.xml和Servlet。

完整的示例代码可以找到on 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(); 
    } 
    } 

} 

回答

15

我得到它的工作。我不得不延长我启动Tomcat 8.0.12服务器的方式。

不过,也有必须要做的三个主要方面:

  1. web-app versionweb.xml中必须是至少3.0(我用3.1
  2. metadata-complete网络。 xml可能不是真实的(default is "false"
  3. classes目录必须在启动之前添加到嵌入式Tomcat中

下面是的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> 

这是我的Tomcat主类的样子(支持现在@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(); 
} 
+0

这个工程有些次,但其他时间导致[神秘异常](https://stackoverflow.com/questions/48979989/)。 – 2018-02-26 18:28:26

0

尝试补充说明:

((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true); 
+4

虽然此代码片段可能会解决问题,但[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code- based-answers)确实有助于提高您的质量帖子。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。 – NathanOliver 2015-12-09 16:11:33