为什么在 Standalone Tomcat 上部署时我的 RequestMapping 没有被拾取?它适用于 Eclipse WTP

Why are my RequestMapping not being picked up when deploying on Standalone Tomcat? It works in Eclipse WTP

我正在使用 RequestMapping 注释在 Tomcat8 上部署一个 Spring MVC webapp。 映射示例:

@Controller("brandController")
@RequestMapping("brand")
public class BrandController {

@Autowired
private BrandService brandService;


/**
 * Creates or edits details about a specific Brand
 * @param brand the brand to create/edit
 */
@RequestMapping(value="/save", consumes="application/json",  produces="application/json", method=RequestMethod.POST)
public @ResponseBody Brand editBrand(@RequestBody Brand brand){
    brandService.saveBrand(brand);
    return brand;
}
...
}

web.xml

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


    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

web.xml 引用 WEB-INF/dispatcher-servlet.xml,内容如下

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

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


<!-- Data Source -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <!-- Production Environment -->
    <property name="driverClass" value="org.postgresql.Driver"/>
    <property name="jdbcUrl" value="jdbc:postgresql://x.x.x.xx/mydb"/>
    <property name="user" value="myuser"/>
    <property name="password" value="mypass" />

    <!-- c3p0 properties -->

    <property name="acquireIncrement" value="3"/>
    <property name="maxIdleTime" value="600"/><!-- seconds -->
    <property name="minPoolSize" value="3"/>
    <property name="maxPoolSize" value="6"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.acme.model"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="nestedTransactionAllowed" value="true"/>
</bean>
<tx:annotation-driven/>


<!-- scan for Spring MVC components -->
<mvc:annotation-driven/>



</beans>

catalina.out 日志如下 (loglevel = INFO)

    26-Jan-2015 13:10:41.459 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
26-Jan-2015 13:10:41.521 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
26-Jan-2015 13:10:41.524 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
26-Jan-2015 13:10:41.525 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
26-Jan-2015 13:10:41.526 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 2574 ms
26-Jan-2015 13:10:41.596 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
26-Jan-2015 13:10:41.601 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.0.3
26-Jan-2015 13:10:41.680 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /home/me/apache-tomcat-8.0.3/webapps/ACME.war
26-Jan-2015 13:10:41.713 WARNING [localhost-startStop-1] org.apache.catalina.startup.SetContextPropertiesRule.begin [SetContextPropertiesRule]{Context} Setting property 'antiJARLocking' to 'true' did not find a matching property.
26-Jan-2015 13:10:47.897 INFO [localhost-startStop-1] org.apache.catalina.util.SessionIdGenerator.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [112] milliseconds.
2015-01-26 13:10:48,187 INFO  [localhost-startStop-1] servlet.FrameworkServlet (FrameworkServlet.java:484) - FrameworkServlet 'dispatcher': initialization started
2015-01-26 13:10:48,218 INFO  [localhost-startStop-1] support.AbstractApplicationContext (AbstractApplicationContext.java:510) - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Mon Jan 26 13:10:48 GMT 2015]; root of context hierarchy
2015-01-26 13:10:48,274 INFO  [localhost-startStop-1] xml.XmlBeanDefinitionReader (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
2015-01-26 13:10:49,172 INFO  [localhost-startStop-1] log.MLog (MLog.java:92) - MLog clients using log4j logging.
2015-01-26 13:10:49,206 INFO  [localhost-startStop-1] c3p0.C3P0Registry (C3P0Registry.java:216) - Initializing c3p0-0.9.2.1 [built 20-March-2013 10:47:27 +0000; debug? true; trace: 10]
26-Jan-2015 13:10:49.604 INFO [localhost-startStop-1] org.hibernate.annotations.common.reflection.java.JavaReflectionManager.<clinit> HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
26-Jan-2015 13:10:49.620 INFO [localhost-startStop-1] org.hibernate.Version.logVersion HHH000412: Hibernate Core {4.3.6.Final}
26-Jan-2015 13:10:49.625 INFO [localhost-startStop-1] org.hibernate.cfg.Environment.<clinit> HHH000206: hibernate.properties not found
26-Jan-2015 13:10:49.629 INFO [localhost-startStop-1] org.hibernate.cfg.Environment.buildBytecodeProvider HHH000021: Bytecode provider name : javassist
2015-01-26 13:10:50,015 INFO  [localhost-startStop-1] impl.AbstractPoolBackedDataSource (AbstractPoolBackedDataSource.java:522) - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge2vb97an867f5dlj3r|2341b2f0, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge2vb97an867f5dlj3r|2341b2f0, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:postgresql://xx.xx.xx.xx/mydb, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 600, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 6, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
26-Jan-2015 13:10:52.102 INFO [localhost-startStop-1] org.hibernate.dialect.Dialect.<init> HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
26-Jan-2015 13:10:52.123 INFO [localhost-startStop-1] org.hibernate.engine.jdbc.internal.LobCreatorBuilder.useContextualLobCreation HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
26-Jan-2015 13:10:52.208 INFO [localhost-startStop-1] org.hibernate.engine.transaction.internal.TransactionFactoryInitiator.initiateService HHH000399: Using default transaction strategy (direct JDBC transactions)
26-Jan-2015 13:10:52.222 INFO [localhost-startStop-1] org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory.<init> HHH000397: Using ASTQueryTranslatorFactory
26-Jan-2015 13:10:52.487 INFO [localhost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaValidator.validate HHH000229: Running schema validator
26-Jan-2015 13:10:52.487 INFO [localhost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaValidator.validate HHH000102: Fetching database metadata
2015-01-26 13:10:52,574 INFO  [localhost-startStop-1] hibernate4.HibernateTransactionManager (HibernateTransactionManager.java:360) - Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge2vb97an867f5dlj3r|2341b2f0, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge2vb97an867f5dlj3r|2341b2f0, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:postgresql://xx.xx.xx.xx/mydb, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 600, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 6, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]] of Hibernate SessionFactory for HibernateTransactionManager
2015-01-26 13:10:53,555 INFO  [localhost-startStop-1] annotation.RequestMappingHandlerAdapter (RequestMappingHandlerAdapter.java:518) - Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Mon Jan 26 13:10:48 GMT 2015]; root of context hierarchy
2015-01-26 13:10:53,604 INFO  [localhost-startStop-1] annotation.RequestMappingHandlerAdapter (RequestMappingHandlerAdapter.java:518) - Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Mon Jan 26 13:10:48 GMT 2015]; root of context hierarchy
2015-01-26 13:10:53,670 WARN  [localhost-startStop-1] view.ContentNegotiatingViewResolver (ContentNegotiatingViewResolver.java:278) - Did not find any ViewResolvers to delegate to; please configure them using the 'viewResolvers' property on the ContentNegotiatingViewResolver
2015-01-26 13:10:53,701 INFO  [localhost-startStop-1] servlet.FrameworkServlet (FrameworkServlet.java:503) - FrameworkServlet 'dispatcher': initialization completed in 5512 ms
26-Jan-2015 13:10:54.334 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
26-Jan-2015 13:10:54.339 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
26-Jan-2015 13:10:54.344 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 12817 ms

现在,如果我通过 Eclipse WTP 部署我的应用程序,映射将被拾取并且应用程序可以正常工作。 但是,当我在 "plain" Tomcat 8 容器中部署应用程序时,映射没有被提取。

注意 Tomcat 的运行时包是完全一样的,唯一的区别是我在 Eclipse 和另一个中使用过它 WEB-INF中部署的libs和类一样,所以我怀疑这与Eclipse自定义的一些设置有关,但我找不到任何相关差异。

你有什么想法吗? 谢谢。

你的控制器在另一个模块中吗?也许 eclipse 将它部署为 类,当你制作 war 文件时,它不再位于当前 类 文件夹中?

p.s:我认为是资源问题。找不到 类 的任何原因。无论如何 :D