SpringMVC-概述
概述 三元组的概念 Model(模型) 数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图) 负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器) 收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。 也就是说控制器做了个调度员的工作,在Web MVC模式下,模型无法主动推数据给视图,如果用户想要视图更新,需要再发送一次请求(即请求-响应模型)。
什么Spring mvc Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
Spring Web MVC也是服务到工作者模式的实现,但进行可优化。前端控制器是DispatcherServlet;
应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response)
方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
Spring MVC能帮我们做什么
让我们能非常简单的设计出干净的Web层和薄薄的Web层;
进行更简洁的Web层的开发;
天生与Spring框架集成(如IoC容器、AOP等);
提供强大的约定大于配置的契约式编程支持;
能简单的进行Web层的单元测试;
支持灵活的URL到页面控制器的映射;
非常容易与其他视图技术集成,如Velocity、FreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model里(Map
数据结构实现,因此很容易被其他框架使用);
非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API;
提供一套强大的JSP标签库,简化JSP开发;
支持灵活的本地化、主题等解析;
更加简单的异常处理;
对静态资源的支持;
支持Restful风格。
Spring MVC架构 Spring Web MVC框架也是一个基于请求驱动的Web框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器(动作/处理器)进行处理。首先让我们整体看一下Spring Web MVC处理请求的流程:
首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;
页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;
前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;
前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。
Spring MVC核心架构图
核心架构的具体流程步骤如下:
首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
DispatcherServlet——>HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
SpringMVC的优势
清晰的角色划分:前端控制器(DispatcherServlet
)、请求到处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器( Validator)、命令对象(Command 请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要;
由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象;
和Spring 其他框架无缝集成,是其它Web框架所不具备的;
可适配,通过HandlerAdapter可以支持任意的类作为处理器;
可定制性,HandlerMapping、ViewResolver等能够非常简单的定制;
功能强大的数据验证、格式化、绑定机制;
利用Spring提供的Mock对象能够非常简单的进行Web层单元测试;
本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
强大的JSP标签库,使JSP编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。
搭建项目 Spring Web MVC 创建项目 .
│ pom.xml ├─src │ └─main │ ├─java │ │ └─com │ │ └─yale │ │ └─controller │ │ HelloWorldController.java │ │ │ ├─resources │ │ dispatcher-servlet.xml │ │ │ └─webapp │ └─WEB-INF │ │ web.xml │ │ │ └─pages │ hello.jsp
pom文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <?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 > <packaging > war</packaging > <name > springmvc5</name > <groupId > com.test</groupId > <artifactId > springmvc5</artifactId > <version > 1.0-SNAPSHOT</version > <properties > <spring.version > 5.2.3.RELEASE</spring.version > </properties > <dependencies > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-web</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.0.1</version > <scope > provided</scope > </dependency > <dependency > <groupId > jstl</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > </dependencies > </project >
web.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <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_3_1.xsd" version ="3.1" > <servlet > <servlet-name > dispatcher</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:dispatcher-servlet.xml</param-value > </init-param > <load-on-startup > 1</load-on-startup > </servlet > <servlet-mapping > <servlet-name > dispatcher</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > </web-app >
dispatcher-servlet.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.yale.controller" /> <bean id ="jspViewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/pages/" /> <property name ="suffix" value =".jsp" /> </bean > </beans >
HelloWorldController 1 2 3 4 5 6 7 8 9 10 11 @Controller @RequestMapping("/hello") public class HelloWorldController { @RequestMapping("sayHi") public String sayHi (@RequestParam("name") String name, ModelMap map) { String message = "Hi, " + name + "!" ; System.out.println(message); map.put("message" ,message); return "hello" ; } }
hello.jsp 1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>HelloWorld</title> </head> <body> ${message} </body> </html>
SpringBoot MVC 创建项目 │ pom.xml │ SpringBootJsp.iml │ ├─.idea │ ├─src │ ├─main │ │ ├─java │ │ │ └─com │ │ │ └─yale │ │ │ │ Application.java │ │ │ │ │ │ │ └─controller │ │ │ IndexController.java │ │ │ │ │ ├─resources │ │ │ application.yml │ │ │ │ │ └─webapps │ │ └─WEB-INF │ │ └─jsp │ │ index.jsp │ │ │ └─test │ └─java
pom文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 <?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/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.yale</groupId > <artifactId > SpringBootJsp</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > war</packaging > <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 1.5.3.RELEASE</version > </parent > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <java.version > 1.8</java.version > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.apache.tomcat.embed</groupId > <artifactId > tomcat-embed-jasper</artifactId > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > jstl</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.xml</include > </includes > </resource > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.*</include > </includes > </resource > <resource > <directory > src/main/webapps</directory > <targetPath > META-INF/resources</targetPath > <includes > <include > **/*.*</include > </includes > </resource > </resources > </build > </project >
application.yml 1 2 3 4 5 spring: mvc: view: prefix: /WEB-INF/jsp/ suffix: .jsp
Controller 1 2 3 4 5 6 7 8 9 10 11 @Controller public class IndexController { @RequestMapping({"/","/index"}) public String index (Map<String,Object> map) { map.put("name" ,"SpringBoot" ); map.put("date" , new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ).format(new Date ())); return "index" ; } }
jsp 1 2 3 4 5 6 7 8 9 <%@page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Spring整合Jsp</title> </head> <body> Hello ${name},当前时间:${date}. </body> </html>