Spring MVC学习总结(一):Spring MVC介绍和入门案例

一、Spring MVC介绍

1、MVC模式

       我们常说的MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。

  • 模型:封装和映射数据。主要用于存储数据以及处理用户请求的业务逻辑。
  • 视图:界面显示工作。主要向控制器提交数据,显示模型中的数据。
  • 控制器:整个网站的跳转逻辑的控制。根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。

       基于Servlet的 MVC 模式的具体实现如下:

  • 模型:一个或多个 JavaBean 对象,用于存储数据(实体模型,由 JavaBean 类创建)和处理业务逻辑(业务模型,由一般的 Java 类创建)。
  • 视图:一个或多个JSP页面,向控制器提交数据和为模型提供数据显示,JSP 页面主要使用 HTML 标记和 JavaBean 标记来显示数据。
  • 控制器:一个或多个 Servlet 对象,根据视图提交的请求进行控制,即将请求转发给处理业务逻辑的 JavaBean,并将处理结果存放到实体模型 JavaBean 中,输出给视图显示。

       基于 Servlet 的 MVC 模式的流程如下:

2、Spring MVC的介绍

       Spring框架提供了构建Web应用程序的全功能MVC模块,即Spring MVC 。Spring MVC框架中提供了一个DispatcherServlet,作为前端控制器来分派请求,同时,提供了灵活的配置处理程序映射、视图解析、语言环境和主题解析,并支持文件上传。其优点如下:

(1)清晰的角色划分:控制器(controller)、验证器(validator)、命令对象(command obect)、表单对象(form object)、模型对象(model object)、Servlet分发器(DispatcherServlet)、处理器映射(handler mapping)、试图解析器(view resoler)等等。每一个角色都可以由一个专门的对象来实现。

(2)强大而直接的配置方式:将框架类和应用程序类都能作为JavaBean配置,支持跨多个context的引用,例如,在web控制器中对业务对象和验证器validator)的引用。

(3)可适配、非侵入:可以根据不同的应用场景,选择何事的控制器子类(simple型、command型、from型、wizard型、multi-action型或者自定义),而不是一个单一控制器(比如Action/ActionForm)继承。

(4)可重用的业务代码:可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。

(5)可定制的绑定(binding)和验证(validation):比如将类型不匹配作为应用级的验证错误,这可以保证错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,需6手动解析它并转换到业务对象。

(6)可定制的handler mapping和view resolution:Spring提供从最简单的URL映射,到复杂的、专用的定制策略。与某些web MVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。

(7)灵活的model转换:在Springweb框架中,使用基于Map的键/值对来达到轻易的与各种视图技术集成。

(8)可定制的本地化和主题(theme)解析:支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等等。

(9)简单而强大的JSP标签库(Spring Tag Library):支持包括诸如数据绑定和主题(theme)之类的许多功能。他提供在标记方面的最大灵活性。

(10)JSP表单标签库:在Spring2.0中引入的表单标签库,使用在JSP编写表单更加容易。

(11)Spring Bean的生命周期:可以被限制在当前的HTTp Request或者HTTp Session。准确的说,这并非Spring MVC框架本身特性,而应归属于Spring MVC使用的WebApplicationContext容器。

二、Spring MVC入门案例

1、helloWorld程序演示

(1)创建maven工程,在pom.xml导入jar包。

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>

(2)在 web.xml 文件中配置DispatcherServlet,具体内容如下:

<?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>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--  指定Spring MVC配置文件的位置    -->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--  
      Servlet一般都是在第一次访问时才加载,此配置表明容器在启动时就立即加载Servlet 
      load-on-startup:服务器启动时创建对象,值越小优先级越高,越先创建对象 
    -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <!--  
        /*和/都是拦截所有请求
        /*:拦截到所有的请求,包括jsp,如果不写,默认值
        /:拦截除*.jsp之外的所有请求
     -->
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

(3)在index.jsp中添加超链接跳转,并在WEB-INF下创建pages目录,建立helloPage.jsp。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<%--SpringMVCStudy_war/--%>
<a href="${pageContext.request.contextPath}/hello">你好</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>helloPage</title>
</head>
<body>
<h3>我是helloPage,你好</h3>
</body>
</html>

(4)创建HelloController类

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String sayHello(){
        System.out.println("我是控制台输出");
        return "helloPage";
    }
}

(5)在resources目录下创建springmvc.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:mvc="http://www.springframework.org/schema/mvc"
       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.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--  配置注解扫描的包  -->
    <context:component-scan base-package="com.yht.example1"></context:component-scan>
    <!--  配置视图解析器 :拼接页面地址 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--    访问路径的前缀    -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--    文件后缀    -->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

       说明: 视图解析器是Spring MVC中的重要组成部分,在上面的配置文件中通过配置视图解析器的中定义了prefix=/WEB-INF/pages/,suffix=.jsp。在index.jsp中点击跳转,请求发送到控制层的hello请求,并通过sayHello()返回目标页面的名称,在这里通过prefix和suffix形成一个拼串的操作(/WEB-INF/pages/helloPage.jsp),并返回至客户端。

 (6)配置tomcat服务器,并启动项目。

启动之后显示index界面,点击超链接。

2、问题总结

(1)关于springmvc.xml配置文件的说明。

如果在web.xml中配置servlet时不指定springmvc.xml的路径,则默认会在WEB-INF目录下寻找名为dispatcherServlet-servlet.xml的配置文件。报错信息如下:

org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)

解决方法一:在init-param中指明springmvc.xml的路径。

解决方法二:在WEB-INF目录下创建dispatcherServlet-servlet.xml

(2)解析错误:$%7BpageContext.request.contextPath%7D。

pageContext被解析为$%7BpageContext.request.contextPath%7D,如下图:

出现原因:通过archetype-webapp生成的web工程,默认创建的web版本为2.3,版本过低。

解决方法:更换版本为更高版本,如:4.0

<?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">
  
</web-app>

(3)出现问题:No mapping found for HTTP request with URI [/SpringMVCStudy_war/] in DispatcherServlet with name 'dispatcherServlet'

出现原因:web.xml中dispatcherServlet配置的不对。因为/*表示匹配所有,因此所有传入的路径都会被匹配到,进而交由DispatcherServlet处理,而“/表示将DispatcherServlet作为default Servlet,所有其他路径映射未匹配情况下才会交由它处理。

错误的配置:

    <servlet-mapping>
		<servlet-name>dispatcherServlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
   <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern></url-pattern>
  </servlet-mapping>

正确的配置:

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

三、Spring MVC工作流程认识

1、常用组件

(1)DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。当用户的请求到达前端控制器,由dispatcherServlet调用其他组件处理用户的请求,决定下一步的操作。

(2)ViewResolver:进行视图解析,根据逻辑视图名解析成真正的视图。ViewResolver负责将处理结果生成View视图,它先根据逻辑视图名解析成物理视图名(即页面的具体地址),然后生成View视图对象,最后对View进行渲染将处理结果通过页面显示给用户。

(3)HandlerMapping:HandlerMapping负责根据用户的请求找到Handler处理器,Spring MVC提供了不同的映射器实现不同的映射方式,如:配置文件方式、实现接口方式、注解方式等。

(4)HandlAdapter:按照特定规则去执行Handler。这里体现了适配器模式,通过扩展适配器可以对更多类型的处理器进行执行。

2、工作流程

Spring MVC工作原理图如下:

从上图可以看到,Spring MVC工作的具体步骤如下:

(1)用户发送请求至前端控制器DispatcherServlet。(index.jsp中点击超链接发起对/hello的请求)

(2)DispatcherServlet收到请求调用HandlerMapping处理器映射器。(配置在web.xml中的dispatcherServlet)

(3) 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

(4)DispatcherServlet调用HandlerAdapter处理器适配器。

(5) HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。(去HelloController找/hello请求是否能被处理)

(6) Controller执行完成返回ModelAndView。(将WEB-INF/pages/helloPage.jsp返回)

(7) HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

(8)DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

(9)ViewReslover解析后返回具体View。

(10)DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

(11) DispatcherServlet响应用户。

 

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/112946994