Openshift Spring MVC Tomcat应用程序的部署路径返回404

Com*_*ist 8 java spring-mvc tomcat7 openshift

I am running a Tomcat7 application using Spring MVC on OpenShift under the domain: financial-datasite.rhcloud.com. I run and test the application locally using a Tomcat server and later push it to the remote repository. Currently, there's only a HomePage and a button underneath redirecting to a different page. When testing locally, both pages display contents as expected. However, when deployed to the remote server, only the HomePage is displayed, and on clicking the button, I get an HTTP 404 error. I have come across various similar questions here, but none of them have helped so far. I have played around configuring the web.xml, pom.xml, servlet-context.xml, and the controller files. However, none of those have helped. I have also been checking the tail files and logs to monitor what's happening, which suggests that the remote server is accessing some 'printWelcome' method (which doesn't even exist in my project) in the controller class for the second page:

INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/Sectors],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.spring.mvc.SectorController.printWelcome(org.springframework.ui.ModelMap)
Run Code Online (Sandbox Code Playgroud)

Here is my project structure. In my localhost, the default page is run as localhost:8181/mvc/ and the second page is run as http://localhost:8181/mvc/Sectors. Similarly, post deployment, the home page is run as http://financial-datasite.rhcloud.com and the second page executed as http://financial-datasite.rhcloud.com/Sectors, which throws a 404 error for /WEB-INF/views/hello.jsp, which, again, doesn't even exist in my project directory. Another thing I observed in the log files are that the code is likely not hitting the SectorController class as I have coded for print commands to be logged, which aren't really getting logged into the console when the page is requested from the deployed site. I am quite unsure about which files are being run on the remote server and if there are any configuration issues that I am unaware of. Following are my web.xml, pom.xml, servlet-context.xml, Sectors.jsp, Google-Maps.js from where I've called the new page to load), and SectorController.java (which is the controller file for the second page). Apologies for a lengthy question, please let me know if you require any more information. Any help would be appreciated, thanks.

web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <display-name>Financial Data Site</display-name>

  <servlet>
    <servlet-name>financial</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>financial</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

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

</web-app>
Run Code Online (Sandbox Code Playgroud)

的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>
    <groupId>com.spring</groupId>
    <artifactId>mvc</artifactId>
    <name>SpringMVC</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>

    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.6.6</org.slf4j-version>

        <!-- Newly Added from here -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>eap</id>
            <url>http://maven.repository.redhat.com/techpreview/all</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>eap</id>
            <url>http://maven.repository.redhat.com/techpreview/all</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
    <!-- Till here -->

    <dependencies>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- MySQL database driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.10.Final</version>
        </dependency>

        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>   

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>

        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

        <!-- JSTL -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>compile</scope>
        </dependency>

        <!-- Tag Library -->
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
          <scope>compile</scope>
        </dependency>

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- When built in OpenShift the 'openshift' profile will be 
                used when invoking mvn. -->
            <!-- Use this profile for any OpenShift specific customization 
                your app will need. -->
            <!-- By default that is to put the resulting archive into the 
                'deployments' folder. -->
            <!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->
            <id>openshift</id>
            <build>
            <finalName>financial</finalName>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.4</version>
                        <configuration>
                            <outputDirectory>webapp</outputDirectory>
                            <warName>ROOT</warName>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>
Run Code Online (Sandbox Code Playgroud)

servlet的context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <annotation-driven />

    <context:component-scan base-package="com.spring.mvc" />

    <resources mapping="/resources/**" location="/resources/" />

    <beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

</beans:beans>
Run Code Online (Sandbox Code Playgroud)

Sectors.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ page session="false"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sectors</title>
</head>

<body>
    <h1>Message</h1>
    <c:if test="${not empty Sectors}">

        <ul>
            <c:forEach var="_SectorNames" items="${Sectors}">
                <li>${_SectorNames}</li>
            </c:forEach>
        </ul>

    </c:if>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

Google-Maps.js:以下代码段仅包含用于在地图上创建div部分以及在新窗口中调用新页面的函数

function HomeControl(controlDiv, map)
{
      // Set CSS for the control border.
      var _ControlUI = document.createElement('div');
      _ControlUI.style.backgroundColor = '#fff';
      _ControlUI.style.border = '2px solid #fff';
      _ControlUI.style.borderRadius = '3px';
      _ControlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
      _ControlUI.style.cursor = 'pointer';
      _ControlUI.style.marginBottom = '22px';
      _ControlUI.style.textAlign = 'center';
      _ControlUI.title = 'Click to filter by Sectors';
      controlDiv.appendChild(_ControlUI);

      // Set CSS for the control interior.
      var _ControlText = document.createElement('div');
      _ControlText.style.color = 'rgb(25,25,25)';
      _ControlText.style.fontFamily = 'Roboto,Arial,sans-serif';
      _ControlText.style.fontSize = '12px';
      _ControlText.style.lineHeight = '38px';
      _ControlText.style.paddingLeft = '5px';
      _ControlText.style.paddingRight = '5px';
      _ControlText.innerHTML = '<strong>View by Sectors</strong>';
      _ControlUI.appendChild(_ControlText);

      // Setup the click event listeners, also calls Sectors page on a new window
      google.maps.event.addDomListener(_ControlUI, 'click', function() {
          //add code here to redirect to Sectors page
          var _Window = window.open('/mvc/Sectors', '__blank');
          _Window.focus();
      });
}
Run Code Online (Sandbox Code Playgroud)

SectorController.java

    package com.spring.mvc;

    import java.text.DateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Locale;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;

    import com.spring.dao.impl.SectorDAOImpl;
    import com.spring.model.Sector;

    @Controller
    public class SectorController {

        private static final Logger logger = LoggerFactory.getLogger(SectorController.class);

        @RequestMapping(value = "/Sectors", method = {RequestMethod.HEAD, RequestMethod.GET})
        public ModelAndView DisplaySectors(Locale locale, Model model) {

            logger.info("Welcome home! You are in: {}.", locale);

            Date date = new Date();
            DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

            String formattedDate = dateFormat.format(date);

            model.addAttribute("serverTime", formattedDate );

            SectorDAOImpl _SectorDAOImpl = new SectorDAOImpl();
            List<Sector> _Sectors = _SectorDAOImpl.GetByID();       
            List<String> _SectorNames = new ArrayList<String>();

            for( Sector sector : _Sectors) {
                _SectorNames.add(sector.getSectorName());
            }

            ModelAndView _ModelAndView = new ModelAndView("Sectors");
            _ModelAndView.addObject("Sectors", _SectorNames);

            return _ModelAndView;
        }
}
Run Code Online (Sandbox Code Playgroud)

Kon*_*nko 4

  1. 正如 Jessai 在评论中指出的那样,

    var _Window = window.open('/mvc/Sectors', '__blank');
    
    Run Code Online (Sandbox Code Playgroud)

    不要明确使用您的项目名称!有多种方法可以获取上下文名称,例如 HttpServletRequest 的 request.getContextPath() 方法。

    在这种情况下,如果使用硬编码 URL 字符串,我认为您可以使用相对 URL,只需“Sectors”或“./Sectors”。

    参考:

  2. '__blank':你的意思是'_blank'?

  3. 顺便一提:

    您正在 Tomcat 7 上进行部署,因此您可以在文件中声明遵守 Servlet 3.0 规范而不是 2.5 web.xml

    请参阅以下内容以在启动时禁用组件扫描:
    https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Configure_your_web_application

  4. INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/Sectors],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.spring.mvc.SectorController.printWelcome(org.springframework.ui.ModelMap)
    
    Run Code Online (Sandbox Code Playgroud)

    如果您的类文件与您的源代码不匹配,则意味着您的代码尚未编译。删除您编译的类(例如 use mvn clean)并重试。

    如果您好奇,您可以使用任何 ZIP 归档应用程序解压您的 war 文件并查看实际内容。

  5. 您或我们公司是否拥有http://spring.com网站的域名?如果不是,请勿使用包名称com.spring,也不要使用<groupId>com.spring</groupId>. 这些名字不属于你。它们是别人的财产。

  6. <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
    
    Run Code Online (Sandbox Code Playgroud)

    如果您使用的是 3.x,为什么不是 3.x 系列中当前的 3.2.12.RELEASE,或者更好的最后一个 4.1.6.RELEASE?Spring Framework 3.1.x 已结束生命周期,不再受支持。