【问题标题】:Why am I getting "HTTP Status 404 - Servlet <servlet name> is not available"为什么我收到“HTTP 状态 404 - Servlet <servlet name> 不可用”
【发布时间】:2015-09-17 15:17:00
【问题描述】:

我正在查看this Spring web MVC tutorial,但我被困在第 1.12 节,我应该看到由我的控制器处理的“Hello”页面,但却得到“HTTP 状态 404 - Servlet 不可用 ”。我查看了其他具有相同错误的 stackoverflow 问题,但没有任何帮助。

以下是相关文件:

/web/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

    <!--
         The "Front Controller" (http://en.wikipedia.org/wiki/Front_Controller_pattern).
         that dispatches requests to registered handlers (Controller implementations).
      -->
    <servlet>
        <servlet-name>filth</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>filth</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

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

</web-app>

/web/WEB-INF/filth-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- the application context definition for the filth DispatcherServlet -->

    <context:component-scan base-package="com.filth.controller"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/web/view/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

/web/view/hello.jsp

<html>
    <head><title>Hello :: Spring Application</title></head>
    <body>
        <h1>Hello - Spring Application</h1>
        <p>Greetings.</p>
     </body>
</html>

/src/main/java/com/filth/controller/HelloController.java

package com.filth.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller for the "Hello" page
 */
@Controller
public class HelloController {

    private static final Log LOGGER = LogFactory.getLog(HelloController.class);

    @RequestMapping(value="/hello.html", method = RequestMethod.GET)
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        LOGGER.info("Returning hello view");

        return new ModelAndView("hello");
    }

}

/build.properties

# Ant properties for building FiLTH

appserver.home=${env.WORKSPACE}/tomcat6
appserver.lib=${appserver.home}/lib
deploy.path=${appserver.home}/webapps

tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=tomcat
tomcat.manager.password=s3cret

/build.xml

<?xml version="1.0"?>

<project name="filth" xmlns:ivy="antlib:org.apache.ivy.ant" basedir="." default="usage">

    <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath>
            <pathelement path="${build.lib.dir}/ant-contrib.jar"/>
        </classpath>
    </taskdef>

    <taskdef name="ivy-configure" classname="org.apache.ivy.ant.IvyConfigure"/>
    <taskdef name="ivy-resolve" classname="org.apache.ivy.ant.IvyResolve"/>
    <taskdef name="ivy-retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>
    <taskdef name="ivy-deliver" classname="org.apache.ivy.ant.IvyDeliver"/> 
    <taskdef name="ivy-publish" classname="org.apache.ivy.ant.IvyPublish"/>

    <target name="ivy-resolve">
        <ivy:configure />

        <ivy:resolve file="${ivy.dep.file}" conf="${ivy.configurations}" />

        <ivy:retrieve pattern="${ivy.retrieve.pattern}" conf="${ivy.configurations}" />
        <echo message="ivy.dep.file: ${ivy.dep.file}"/>
        <echo message="ivy.configurations: ${ivy.configurations}"/>
        <echo message="ivy.retrieve.pattern: ${ivy.retrieve.pattern}"/>
    </target>

    <property environment="env"/>

    <property file="build.properties"/>
    <property file="build.passwords.properties" />

    <property name="src.dir" value="src/main/java"/>
    <property name="test.dir" value="src/test"/>
    <property name="web.dir" value="web/"/>
    <property name="build.dir" value="target"/>
    <property name="name" value="filth"/>
    <property name="resources.dir" value="src/main/resources"/>

    <path id="master-classpath">
        <fileset dir="lib">
            <include name="**/*.jar"/>
        </fileset>
        <!-- We need the servlet API classes: -->
        <!--  * for Tomcat 5/6 use servlet-api.jar -->
        <!--  * for other app servers - check the docs -->
        <fileset dir="${appserver.lib}">
            <include name="servlet*.jar"/>
        </fileset>
        <pathelement path="${resources.dir}"/>
        <pathelement path="${build.dir}"/>
    </path>

    <target name="usage">
        <echo message=""/>
        <echo message="${name} build file"/>
        <echo message="-----------------------------------"/>
        <echo message=""/>
        <echo message="Available targets are:"/>
        <echo message=""/>
        <echo message="build     --> Build the application"/>
        <echo message="deploy    --> Deploy application as directory"/>
        <echo message="deploywar --> Deploy application as a WAR file"/>
        <echo message="install   --> Install application in Tomcat"/>
        <echo message="reload    --> Reload application in Tomcat"/>
        <echo message="start     --> Start Tomcat application"/>
        <echo message="stop      --> Stop Tomcat application"/>
        <echo message="list      --> List Tomcat applications"/>
        <echo message=""/>
    </target>

    <target name="build" description="Compile main source tree java files">
        <mkdir dir="${build.dir}"/>
        <javac destdir="${build.dir}" source="1.6" target="1.6" debug="true"
               deprecation="false" optimize="false" failonerror="true">
            <src path="${src.dir}"/>
            <classpath refid="master-classpath"/>
        </javac>
    </target>

    <target name="deploy" depends="build" description="Deploy application">
        <copy todir="${deploy.path}/${name}" preservelastmodified="true">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </copy>
    </target>

    <target name="deploywar" depends="build" description="Deploy application as a WAR file">
        <war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </war>
        <copy todir="${deploy.path}" preservelastmodified="true">
            <fileset dir=".">
                <include name="*.war"/>
            </fileset>
        </copy>
    </target>

    <target name="buildtests" description="Compile test tree java files">
        <mkdir dir="${build.dir}"/>
        <javac destdir="${build.dir}" source="1.6" target="1.6" debug="true"
            deprecation="false" optimize="false" failonerror="true">
            <src path="${test.dir}"/>
            <classpath refid="master-classpath"/>
        </javac>
    </target>

    <target name="tests" depends="build, buildtests" description="Run tests">
        <junit printsummary="on"
            fork="false"
            haltonfailure="false"
            failureproperty="tests.failed"
            showoutput="true">
            <classpath refid="master-classpath"/>
            <formatter type="brief" usefile="false"/>

            <batchtest>
                <fileset dir="${build.dir}">
                    <include name="**/*Test.*"/>
                </fileset>
            </batchtest>
        </junit>

        <fail if="tests.failed">
            tests.failed=${tests.failed}
            ***********************************************************
            ***********************************************************
            ****  One or more tests failed!  Check the output ...  ****
            ***********************************************************
            ***********************************************************
        </fail>
    </target>

<!-- ============================================================== -->
<!-- Tomcat tasks - remove these if you don't have Tomcat installed -->
<!-- ============================================================== -->

    <path id="catalina-ant-classpath">
        <!-- We need the Catalina jars for Tomcat -->
        <!--  * for other app servers - check the docs -->
        <fileset dir="${appserver.lib}">
           <include name="catalina-ant.jar"/>
           <include name="tomcat-coyote.jar"/>
           <include name="tomcat-util.jar"/>
        </fileset>
        <fileset dir="${appserver.home}/bin">
           <include name="tomcat-juli.jar"/>
        </fileset>
    </path>

    <taskdef name="install" classname="org.apache.catalina.ant.DeployTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="list" classname="org.apache.catalina.ant.ListTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="start" classname="org.apache.catalina.ant.StartTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>

    <target name="install" description="Install application in Tomcat">
        <install url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"
                 war="${name}"/>
    </target>

    <target name="reload" description="Reload application in Tomcat">
        <reload url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="start" description="Start Tomcat application">
        <start url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="stop" description="Stop Tomcat application">
        <stop url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="list" description="List Tomcat applications">
        <list url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"/>
    </target>

<!-- End Tomcat tasks -->

</project>

/ivy.xml

<ivy-module version="2.0">
    <info organisation="org.apache" module="hello-ivy"/>
    <dependencies>
        <dependency org="org.springframework" name="spring-context" rev="4.1.6.RELEASE"/>
        <dependency org="org.springframework" name="spring-webmvc" rev="4.1.6.RELEASE"/>
        <dependency org="commons-logging" name="commons-logging" rev="1.2"/>
        <dependency org="javax.servlet" name="servlet-api" rev="2.5"/>
        <dependency org="junit" name="junit" rev="4.12"/>
    </dependencies>
</ivy-module>

导航到http://localhost:8080/filth/hello.html 时出现错误。 catalina.out 没有给出任何错误,我确实看到了来自 HelloController.java 的日志条目,但非常不一致——也不知道为什么会这样。

请注意,http://localhost:8080/filth/index.jsphttp://localhost:8080/filth/view/hello.jsp 工作 - 只是通过 Controller 无法按预期工作。

有人有什么想法吗? 如果您需要更多上下文/信息,请告诉我。 谢谢!

【问题讨论】:

  • 试试http://localhost:8080/hello.html 你的DispatcherServlet 映射到/,而不是/filth
  • 你的项目/jar文件的名字是什么,是不是很脏??如果是这样,调用 url 看起来是正确的。另外,如果您使用的是 maven plz share pom 。您是否还检查了 jar 的部署位置是否部署了所有必需的资源?我对部署有疑问,因为其他所有看起来都很完美。
  • @Evgeni:localhost:8080/hello.html 也得到 404:“请求的资源 (/hello.html) 不可用。”我应该注意到localhost:8080/filth/index.jsplocalhost:8080/filth/view/hello.jsp 工作——它只是通过不工作的控制器。
  • @Bhupi:是的,“filth”是项目的名称。我在 build.xml、build.properties 和 ivy.xml 上添加了内容。我在 [tomcat dir]/webapps 中看到了一个 filth/ 目录以及 filth.war,其中仅包含以下内容:index.jsp、view/hello.jsp、WEB-INF/web.xml 和 WEB-INF/filth -servlet.xml。

标签: spring spring-mvc tomcat servlets http-status-code-404


【解决方案1】:

想通了。我没有在部署中包含必要的 jar 依赖项——在 WEB-INF 中添加了一个 lib/ 目录,并在其中放置了必要的运行时依赖项(“部署”ant 目标从那里获取了它)。我之前没有看到这个错误,因为我没有查看正确的日志文件——终于看到日志输出到 [tomcat]/logs/localhost...log。

【讨论】:

    猜你喜欢
    • 2012-06-01
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2021-03-22
    • 2015-10-09
    • 1970-01-01
    相关资源
    最近更新 更多