Spring MVC 为什么这个 Hello World 在没有注释驱动标签的情况下运行良好(与任何其他 Spring 项目不同)

2024-03-22

我已经开始学习 Spring MVC 阅读本教程:http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/ http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/

好吧,这对我来说很清楚。

在这个例子中我有web.xml文件来配置我的网络应用程序:

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

<display-name>Spring3MVC</display-name>
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

And the spring-servlet.xml用于配置 mu DispatcherServlet 的文件:

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan
    base-package="net.viralpatel.spring3.controller" />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

而且,正如您在上一个链接中看到的,我只有一个控制器类来处理针对“/hello”URL 的 HTTP 请求...好吧...这对我来说很清楚...

在此示例旁边,我通过 STS\Eclipse 中的相关模板项目创建了一个新的 Spring MVC 项目。

此示例与上一个示例非常相似:我始终使用 web.xml 文件来配置我的 Web 应用程序、一个用于配置 DispatcherServlet 的文件以及一个处理 HTTP 请求的控制器类。

但有一些我无法理解的区别。

这是我的web.xml配置文件:

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

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->

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


<!-- Creates the Spring Container shared by all Servlets and Filters -->

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

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</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>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

这就是servlet-context.xml文件(配置我的 DispatcherServlet 的配置文件):

<?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">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:component-scan base-package="com.mycompany.maventestwebapp" />
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

好的,正如您所看到的,两个示例的配置文件存在一些差异:

在STS\Eclipse创建的项目中,在servlet-context.xml文件我有这些配置,这些配置在我发布的第一个示例中不存在:

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

好的...我已经阅读了很多有关此配置标签的文档:意味着您可以定义 Spring beans 依赖项,而实际上不必在 xml 中指定一堆元素或实现接口或扩展基类。当 spring 启动时,它会读取它的 xml 配置文件并查找 Foo 是否用 @Controller 进行标记,它知道该类是一个控制器并将其视为控制器。默认情况下,spring 假定它应该管理的所有类都在 beans.xml 文件中显式定义。然后是元件扫描标签告诉 Spring 它应该在类路径中搜索 com.mycompany.maventestweapp 下的所有类,并查看每个类以查看它是否有 @Controller、@Repository、@Service 或 @Component,以及是否有然后 Spring 将向 bean 工厂注册该类,就像您在 xml 配置文件中键入一样。布拉布拉布拉 等等 布拉布拉

好吧,这对我来说绝对清楚!我认为我可以毫无问题地理解为什么我有注释驱动我的第二个示例的 DispatcherServlet 配置文件中的标记,这一点很清楚。

问题是要理解为什么我的第一个示例的 DispatcherServlet 配置文件中没有此标记以及为什么它运行良好如果我尝试从 servlet-context.xml 文件中删除此标记(在我的第二个示例中),则该标记不会运行并出现错误,提示我:HTTP 状态 404 -在堆栈跟踪中我有:警告:org.springframework.web.servlet.PageNotFound - 在名为“appServlet”的 DispatcherServlet 中未找到带有 URI [/maventestwebapp/] 的 HTTP 请求的映射

我认为这是合理的行为,因为 Spring 没有启用注释支持,因此没有注册我的控制器类(使用注释驱动并使用 @Controller 注释我的控制器类,如果我在 bean.xml 中显式定义了此类)文件),所以不能使用这个 bean 的方法来处理 HTTP 请求...好吧...这听起来不错...

但是为什么在第一个示例中没有注释驱动标签就可以工作呢?我没有注释驱动的标签(所以我不允许使用注释来声明什么类是 Spring bean,例如控制器)并且我没有在 beans.xml 文件中显式声明此类...所以不应该当我删除注释驱动标签时,第二个示例不起作用...但它起作用:-/

我要疯狂地理解为什么......

拜托,你能帮我吗?

太感谢了

Andrea


<mvc:annotation-driven>是一个提供附加服务的辅助标签:

  • 注册默认处理程序映射
  • 消息转换(例如将控制器中返回的对象转换为JSON)
  • JSR 303 验证(@Valid 注释)
  • 转换服务(如果指定了转换器,则控制器将能够将实体作为参数,即请求中的文本 ID 将通过 MVC 层转换为实际业务对象。对于日期、枚举等其他对象也是如此.)
  • 也许新版本的 Spring 会添加更多功能。

它是用注解驱动Bean定义解析器 http://www.jarvana.com/jarvana/view/org/springframework/spring-webmvc/3.0.1.RELEASE/spring-webmvc-3.0.1.RELEASE-sources.jar!/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java?format=ok在 org.springframework.web.servlet.config 包中

It's not如果您有适当的映射(如果需要,您可以显式添加所需的 bean https://stackoverflow.com/questions/3693397/howto-get-rid-of-mvcannotation-driven)。 但是,如果您想做一些或多或少的高级工作,例如 JSR 303 验证、使用 JSON 实现 REST 服务、为 MVC 注册转换服务,则此标记非常有用,因为它将这些服务的配置保留在一个位置。

这就是为什么它被包含在 Spring 模板项目中(模板项目是开发 Spring 应用程序的起点(所以你可以去把@Responsebody关于控制器方法返回的值 http://blog.springsource.org/2010/01/25/ajax-simplifications-in-spring-3-0/或者添加一个 MVC 转换器)而不仅仅是 Spring 学习者的一个示例)。

另请注意Spring 3.1 中的处理程序映射配置发生了变化 http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-31-vs-30:

在 Spring 3.1 之前,类型和方法级别的请求映射是 分两个单独的阶段进行检查——首先选择控制器 DefaultAnnotationHandlerMapping 和要调用的实际方法 AnnotationMethodHandlerAdapter 缩小了第二个范围。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring MVC 为什么这个 Hello World 在没有注释驱动标签的情况下运行良好(与任何其他 Spring 项目不同) 的相关文章

随机推荐

  • 单表继承和Yaml配置

    我想在我的项目中使用 symfony2 doctrine 的单表继承 但我找不到任何带有 yaml 配置的工作示例 官方文档中仅提供了注释配置 我找到了 xml 示例 但我想使用 yaml 配置 有人可以帮助并分享一些工作代码吗 好的内置转
  • 如何使用迭代器迭代二维ArrayList?

    我想迭代二维ArrayList包括String使用迭代器的对象 我还想以一种让我选择是否要首先水平 行 迭代还是垂直 列 迭代的方式使用boolean价值 我怎样才能在java中实现这个 到目前为止我已经尝试过的 public class
  • 如何在 MySQL 中执行“如果不存在则插入”?

    我首先通过谷歌搜索找到了这篇文章如何在标准 SQL 中编写 INSERT if NOT EXISTS 查询 http www xaprb com blog 2005 09 25 insert if not exists queries in
  • 如何在 C++ 中验证字符串是否为有效的 IPv4 地址?

    我不需要验证 IP 地址是否可达或类似的内容 我只想验证该字符串是否采用点分四组 xxx xxx xxx xxx IPv4 格式 其中 xxx 介于 0 到 255 之间 您可能想要内特 pton http man7 org linux m
  • 我可以在 AWS Lambda 函数上存储临时文件吗?

    我正在编写一个用于文件提取的 lambda 函数 并且需要在执行此函数时存储文件 因此需要将该文件存储在 aws lambda function 中 是否可以在 lambda 上存储文件 是的 引用自 AWS Lambda 常见问题解答 每
  • Visual Studio 2010 Express。写入输出窗口

    我是 Visual Studio 和 Windows Phone 7 开发新手 我确实激活了重定向所有输出文本选项 但 Debug Writeline 或 Console WriteLine 都不起作用 我如何记录信息 我也花了一段时间才找
  • 分布式任务队列(例如 Celery)与 crontab 脚本

    我无法理解 分布式任务队列 的用途 例如 python 的芹菜库 http www celeryproject org 我知道在 python 框架 celery 中 您可以设置定时窗口来执行函数 然而 这也可以在针对 python 脚本的
  • PostgreSQL 无法打开文件“base/xxxx/xxxxx”没有这样的文件或目录

    最近 我的 Linux 机器上出现了硬件故障 在修复硬件问题并恢复我的 Linux 机器后 当我对其中一个表执行查询时 返回以下错误 ERROR could not open file base 17085 281016 No such f
  • 创建动态分组依据

    df data frame A c 1 4 5 13 2 B c Group 1 Group 3 Group 2 Group 1 Group 2 C c Group 3 Group 2 Group 1 Group 2 Group 3 df
  • GUI 作为有限状态机

    为了实现应用程序的 GUI 我希望将所有逻辑从一种形式集中到另一种形式 该 GUI 管理器将充当有限状态机 虽然我想我在某处见过这种实现 但我找不到与这种解决方案相匹配的设计模式 表单将如下所示 public class Login For
  • 因它能做什么或因为它做了而关闭

    好吧 这是一个有点迂腐的问题 但我想确保我正确理解了这个定义 闭包绰号是用来描述匿名函数的can提升局部作用域中的变量 无论它们实际上是否这样做 或仅当它们do在局部范围内提升变量 换句话说 如果匿名函数具有ability在其本地范围内提升
  • 从 .lm.fit() 计算 p 值的快速方法

    我正在运行模拟并拟合线性模型 lm fit https www rdocumentation org packages pbdDMAT versions 0 4 2 topics lm fit 尽管速度极快 但该函数不提供预测变量的 p 值
  • 如何仅使用 GPX 文件进行 UI 测试

    我正在尝试使用 GPX 文件来模拟运行 UI 测试时的位置 我已在 测试位置 下选择了 GPX 文件 但这不起作用 我刚刚收到一个错误 告诉我 位置不可用 我知道 我可以进入 运行 gt 调试 然后激活 允许位置模拟 然后选择该文件作为 默
  • 从 GWT 访问 Web 服务

    有什么方法可以使用 GWT 的 WSDL 访问 Web 服务吗 以前我试图使用 ws import 生成的类 但后来有人向我指出 GWT 无法处理所有 Java 只能处理它的一个子集 因此它无法理解 ws import 类 感谢致敬 Krt
  • 为什么默认情况下不使用 Control.Monad.Instances 实现 (->)

    我正在读书LYAH http learnyouahaskell com functors applicative functors and monoids 它说我需要显式加载Control Monad Instances使以下语法起作用 f
  • 验证关联的唯一性

    给定以下课程 class Candidate has many applications has many companies through gt job offers end class JobOffer belongs to comp
  • c++ 仅读取文本文件最后一行的最快方法?

    我只想读取文本文件的最后一行 我在 UNIX 上 可以使用 Boost 我知道的所有方法都需要扫描整个文件才能获取最后一行 这根本没有效率 有没有一种有效的方法只获取最后一行 另外 我需要它足够强大 即使有问题的文本文件不断被另一个进程附加
  • 使用 c:foreach (JSP/JSTL) 迭代 ArrayList,变量不起作用

    我知道 关于我的问题有无数的例子 但我经历了很多 但无法弄清楚我的错误在哪里 我正在迭代 ArrayList TestSzenario TestSzenario 类包含一个名为 name 的字符串变量 具有适当的 getter 和 sett
  • SQLWITH子句示例[重复]

    这个问题在这里已经有答案了 我试图了解如何使用WITH条款和目的WITH clause 我所明白的是 WITH子句是普通子查询的替代品 谁能用一个小例子详细向我解释这一点 SQL WITH 子句是 Oracle 在 Oracle 9i 第
  • Spring MVC 为什么这个 Hello World 在没有注释驱动标签的情况下运行良好(与任何其他 Spring 项目不同)

    我已经开始学习 Spring MVC 阅读本教程 http viralpatel net blogs spring 3 mvc create hello world application spring 3 mvc http viralpa