【问题标题】:tomcat cannot find the servlet at the package path [closed]tomcat 在包路径中找不到 servlet [关闭]
【发布时间】:2020-02-05 21:02:49
【问题描述】:

“java”目录中有我的servlet:

@WebServlet("HelloWebServlet")
public class HelloWebServlet extends HttpServlet {

private HttpServletRequest request;
private String title = "Servlet test app";

public void doPost(HttpServletRequest req, HttpServletResponse resp) {

    doGet(req, resp);

} // end: doPost()

private void sendHead(HttpServletResponse resp) {

    try {

        PrintWriter writer = resp.getWriter();

        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");

        writer.println("<HTML>");
        writer.println("<HEAD>");
        writer.println("<meta charset=\"UTF-8\">");
        writer.println("<TITLE>" + title + "</TITLE>");
        writer.println("</HEAD>");
        writer.println("<BODY>");

    } catch (Exception e) {

            throw new Error(e);

    }

} // END: sendHead()

private void sendFlooter(HttpServletResponse resp) {

    try {

        PrintWriter writer = resp.getWriter();
        writer.println("</BODY>");
        writer.println("</HTML>");

    } catch (Exception e) {
        throw new Error(e);
    }

} // END: sendHead()

public void doGet(HttpServletRequest req, HttpServletResponse resp) {

    this.request = req;

    try {

        sendHead(resp);

        PrintWriter writer = resp.getWriter();

        writer.println("<CENTER>");
        writer.println("<FORM>");
        writer.println("<H1>Input your request</H1>");
        writer.println("<INPUT TYPE=\"submit\" value=\"" + "Send" + "\" />");
        writer.println("</FORM>");
        writer.println("</CENTER>");

        sendFlooter(resp);

    } catch (Exception e) {

            throw new Error(e);

    }

} // END: doGet()

} //END: class HelloWebServlet

有web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    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_4_0.xsd"
    version="4.0">

    <display-name>Servlet test app</display-name>

 <servlet-mapping>
     <servlet-name>HelloWebServlet</servlet-name>
     <url-pattern>/hello</url-pattern>
 </servlet-mapping>

</web-app>

还有 index.html 文件:

<html>
<head>
    <meta charset="UTF-8">
    <title>Request from servlet</title>
</head>
<body>

<form action="./hello" method="POST">
    <center>
        <h1>Send request</h1>
        <form>
            <input NAME="Request" TYPE="submit" VALUE="Request from servlet"/>
        </form>
    </center>
</form>

</center>
</body>
</html>

当我的 servlet 类在“java”目录中时,它可以完美运行。但是,如果我尝试将其移动到某个包中,例如在 HelloWebApp 的第一行添加“package info.bhrigu.spring.test.servlets”:

package info.bhrigu.spring.test.servlets; // <------- now in the package!

@WebServlet("HelloWebServlet")
public class HelloWebServlet extends HttpServlet {
private static ArrayList<String> text;
...

并将 web.xml 更改为:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd" version="4.0">

<description>Servlet test app</description>
<display-name>Servlet test app</display-name>

<servlet>
    <servlet-name>HelloWebServlet</servlet-name>
    <servlet-class>info.bhrigu.spring.test.servlets.HelloWebServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HelloWebServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

</web-app>

然后我从 tomcat 收到该类丢失的消息:

HTTP Status 500 – Internal Server Error

Type Exception Report

Message Error instantiating servlet class [info.bhrigu.spring.test.servlets.HelloWebServlet]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Error instantiating servlet class [info.bhrigu.spring.test.servlets.HelloWebServlet] org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)

Root Cause

java.lang.ClassNotFoundException: info.bhrigu.spring.test.servlets.HelloWebServlet

如何为某个包中的servlet编写正确的配置?

【问题讨论】:

  • 你是不是把你的java源文件放到java/info/bhrigu/spring/test/servlets目录下,编译好的class文件在WEB-INF/classes/info/bhrigu/spring/test/servlets ?
  • 你是如何编译这个的?例如,Maven 有一个定义的位置来放置您的类和 HTML/JSP 文件,以便以正确的方式打包它。其他构建环境的工作方式类似。
  • @Selaron 是的,问题是我将我的类文件保存在 /classes 文件夹中而没有竞争路径。谢谢。
  • @stdunbar 我用 JAR 插件编译它(就像一个普通的 jar),但我自己创建内部文件结构。可以在 Maven 中实现。

标签: java tomcat servlets web.xml


【解决方案1】:

我建议您一起删除您的 web.xml 文件。因为您使用的是较新的注释,所以不需要它。

要映射到特定的 URL,请使用如下注释:

@WebServlet("/hello")
public class HelloWebServlet extends HttpServlet {

其次,您不是在制作.jar 文件,而是在制作.war 文件。你的 pom.xml 应该反映:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <artifactId>your-artifact-id</artifactId>
    <groupId>info.bhrigu</groupId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.2</version>
            </plugin>
         </plugins>
    </build>
</project>

目录结构类似于:

pom.xml
src/
    main/
        java/
            info/
                bhrigu/
                    spring/
                        test/
                            servlets/
                                HelloWebServlet.java
        webapp/
            index.html

如果你真的想使用 web.xml(有时仍然需要它),你的结构将是:

pom.xml
src/
    main/
        java/
            info/
                bhrigu/
                    spring/
                        test/
                            servlets/
                                HelloWebServlet.java
        webapp/
            WEB-INF/
                web.xml
            index.html

【讨论】:

  • 网络插件在 IntelliJ 社区版中不可用,不是吗?
  • 恐怕我不确定。但是 pom.xml 中的 war 插件可以正常使用——它不是 IntelliJ 的一部分。您可以创建一个 .war 文件并将其部署到任何 Web 容器(Tomcat、Wildfly、Jetty 等)。
【解决方案2】:

感谢@Selaron。正确答案是 .war 文件中的类路径必须包含原始目录结构。如果我使用像 info.bhrigu.spring.test.servlets.HelloWebServlet 这样的包,那么我必须将 /class 目录的这个结构保存在 .war 文件中,并将其放在 \WEB-INF\classes\info\bhrigu\spring\test\ servlets\HelloWebServlet.class 文件夹,而不是直接在 \WEB-INF\classes 中。

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    相关资源
    最近更新 更多