- MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式。
- 学习内容
- Springmvc介绍
- Springmvc架构讲解
- Springmvc入门
- Springmvc整合mybatis
- 参数绑定
a) Springmvc默认支持的类型
b) 简单数据类型
c) Pojo类型
d) Pojo包装类型
e) 自定义参数绑定
f) 数组类型的参数绑定
g) List类型的绑定 - Springmvc和struts2的区别
1. Spring web mvc介绍
Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的Web应用程序提供全面的基础架构支持非常容易和非常快速。
Spring框架最初由Rod Johnson撰写,并于2003年6月根据Apache 2.0许可证首次发布。
本教程是基于2015年3月发布的Spring Framework版本4.1.6编写的。
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。
模型(Model)封装了应用程序数据,通常它们将由POJO类组成。
视图(View)负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。
控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
Spring web mvc和Struts2都属于**表现层的框架**,它是Spring框架的一部分,我们可以 从Spring的整体结构中看得出来:
Spring MVC加载流程(简图)+架构图
Spring Web模型 - 视图 - 控制器(MVC)框架是围绕DispatcherServlet设计的,它处理所有的HTTP请求和响应。
Spring Web MVC DispatcherServlet的请求处理工作流如下图所示:
以下是对应于到DispatcherServlet的传入HTTP请求的事件顺序:
- 用户发送请求至前端控制器 DispatcherServlet。
- DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。 - DispatcherServlet 通过 HandlerAdapter 处理器适配器调用处理器。
- HandlerAdapter 执行处理器(handler,也叫后端控制器)。
- Controller 执行完成返回 ModelAndView。
- HandlerAdapter 将 handler 执行结果 ModelAndView 返回给 DispatcherServlet。
- DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
- ViewReslover 解析后返回具体 View 对象。
- DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet 响应用户。
关系描述
-
DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。 -
HandlerMapping:处理器映射器
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 -
Handler:处理器
Handler 是继 DispatcherServlet 前端控制器的后端控制器,在 DispatcherServlet 的控制下Handler 对具体的用户请求进行处理。
由于 Handler 涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
-
HandlAdapter:处理器适配器
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 -
View Resolver:视图解析器
View Resolve r负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。 -
View:视图
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView 等。我们最常用的视图就是jsp。
详细描述
- 读取配置文件
- servlet–web.xml contrller 控制器在哪里?
-application.xml service-- 业务层在哪里?
------------------> 读到内容进行初始化
(1) 加载配置文件(类上面的@xxxx)
(2) 扫描用户配置包下的类
(3) 反射机制实例化包下的类
(4)初始化HandlerMapping
-------------->运行
1.异常拦截
2.获取请求传入的参数并处理参数
3.初始化好的handlerMapping中拿出url 对应的方法名,反射调用
Spring架构图, MVC
-
Spring核心功能
IOC ,DI---- 控制反转,依赖注入
AOP–面向切面编程 -
MVC 是一种设计模式 (视图 ,控制器 模型)
-
Spring MVC 是什么?
现在最好的MVC框架
优点
-
简单容易,程序起点高 优秀
-
灵活 扩展性强
核心组件
@Controller
描述了当前这个类是MVC控制器类
@RequestMapping
在处理器映射器哪里起作用
开始一个项目
学习一个新的mvc框架从以下方面入手
- 环境搭建(实现helloworld)
- 如何传递参数到controller
- 如何从控制器获取参数
- 如何完成文件的上传
- 如何完成验证
- 异常的处理
- 拦截器
1. 导包
代码
商品对象
Items.java
package cn.atcast.pojo;
import java.util.Date;
public class Items {
private Integer id;
private String name;
private BigDecimal price;//对于精度比较高的东西,比如money,我会用decimal类型,不会考虑float,double,因为他们容易产生误差
private String pic;
private Date createtime;
private String detail;
WebContent/WEB-INF/web.xml
需要通过使用web.xml文件中的URL映射来映射希望DispatcherServlet处理的请求。
- spirngMvc前端控制器
- 请求跳转
<?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" 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>springmvc0523</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- spirngMvc前端控制器 -->
<servlet>
<servlet-name>spirngmvc01</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 指定springMvc核心配置文件位置 src 下--- classpath是web项目的类路径,可以理解为classes下面。因为无论这些配置文件放在哪,编译之后如果没有特殊情况的话都直接在classes下面。-->
<!-- tomcat启动的时候就加载这个servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spirngmvc01</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
-
web.xml文件将保存Web应用程序的WebContent/WEB-INF目录。
-
在spirngmvc01 DispatcherServlet初始化时,框架将尝试从位于应用程序的WebContent/WEB-INF目录中的名为[servlet-name]-springmvc.xml的文件加载应用程序上下文。
-
接下来,< servlet-mapping>标记指示哪些URL将由DispatcherServlet处理。
这里所有以.action结尾的HTTP请求都将由HelloWeb DispatcherServlet处理。 -
如果不想使用默认文件名为[servlet-name]-springmvc.xml和默认位置为WebContent/WEB-INF,可以通过在web.xml文件中添加servlet侦听器ContextLoaderListener来自定义此文件名和位置 如下:
<web-app...>
<!-------- DispatcherServlet definition goes here----->
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
知识点补充:映射匹配过程
容器的Context对象对请求路径(URL)做出处理,去掉请求URL的上下文路径后,按路径映射规则和Servlet映射路径(< url- pattern>)做匹配,如果匹配成功,则调用这个Servlet处理请求。
servlet容器对url的匹配过程:
当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,
比如我访问的是http://localhost/test/aaa.html,我的应用上下文是test,
容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做servlet的映射匹配。
这个映射匹配过程是有顺序的,而且当有一个servlet匹配成功以后,就不会去理会剩下的servlet了(filter不同,后文会提到)。
其匹配规则和顺序如下:
-
精确路径匹配。例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。
-
最长路径匹配。例子:servletA的url-pattern为/test/,而servletB的url-pattern为/test/a/,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
-
扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action
-
如果前面三条规则都没有找到一个servlet,容器会根据url选择对应的请求资源。如果应用定义了一个default servlet,则容器会将请求丢给default servlet(什么是default servlet?)。
根据这个规则表,就能很清楚的知道servlet的匹配过程,所以定义servlet的时候也要考虑url-pattern的写法,以免出错。
为了让Servlet能响应用户请求,还必须将Servlet配置在web应用中,配置Servlet需要修改web.xml文件。**
--------从Servlet3.0开始,配置Servlet有 两种方式:-----
1.在Servlet类中使用@WebServlet Annotation进行配置。
2.在web.xml文件中进行配置。
我们用web.xml文件来配置Servlet,需要配置< servlet>和< servlet-mapping>。
< servlet>用来声明一个Servlet。
< icon>、< display-name>和< description>元素的用法和< filter>的用法相同。
< init-param>元素与< context-param>元素具有相同的元素描述符,可以使用< init-param>子元素将初始化参数名和参数值传递给Servlet,访问Servlet配置参数通过ServletConfig对象来完成,ServletConfig提供如下方法:
java.lang.String.getInitParameter(java.lang.String name):用于获取初始化参数
ServletConfig获取配置参数的方法和ServletContext获取配置参数的方法完全一样,只是ServletConfig是取得当前Servlet的配置参数,而ServletContext是获取整个Web应用的配置参数。
---<description>、<display-name>和<icon>-----
< description>:为Servlet指定一个文本描述。
< display-name>:为Servlet提供一个简短的名字被某些工具显示。
< icon>:为Servlet指定一个图标,在图形管理工具中表示该Servlet。
< servlet-name>、< servlet-class>和< jsp-file>元素
< servlet>必须含有< servlet-name>和< servlet-class>,
或者< servlet-name>和< jsp-file>。
描述如下:
< servlet-name>用来定义servlet的名称,该名称在整个应用中必须是惟一的
< servlet-class>用来指定servlet的完全限定的名称。
< jsp-file>用来指定应用中JSP文件的完整路径。这个完整路径必须由/开始。
< load-on-startup>
如果load-on-startup元素存在,而且也指定了jsp-file元素,则JSP文件会被重新编译成Servlet,同时产生的Servlet也被载入内存。的内容可以为空,或者是一个整数。这个值表示由Web容器载入内存的顺序。
举个例子:
如果有两个Servlet元素都含有< load-on-startup>子元素,则< load-on-startup>子元素值较小的Servlet将先被加载。如果< load-on-startup>子元素值为空或负值,则由Web容器决定什么时候加载Servlet。如果两个Servlet的< load-on-startup>子元素值相同,则由Web容器决定先加载哪一个Servlet。
<load-on-startup>1</load-on-startup>表示启动容器时,初始化Servlet。
<servlet-mapping>
<servlet-mapping>含有<servlet-name>和<url-pattern>
<servlet-name>:Servlet的名字,唯一性和一致性,与<servlet>元素中声明的名字一致。
<url-pattern>:指定相对于Servlet的URL的路径。该路径相对于web应用程序上下文的根路径。<servlet-mapping>将URL模式映射到某个Servlet,即该Servlet处理的URL。
cn.atcast.controller/ ItemsController 控制层最开始的用法
@Controller
public class ItemsController {
// url到请求方法的指定映射
//http://localhost:8080/springmvc01/list.action
@RequestMapping("list")
public ModelAndView itemsList() throws Exception{
List<Items> itemList = new ArrayList<Items>();
// 商品列表
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemList.add(items_1);
itemList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemList",itemList); //假设从后台拿上来的
modelAndView.setViewName("itemList");//跳转到指定的页面 --/WEB-INF/jsp/itemList.jsp
return modelAndView;
}
}
ModelAndView 模型和视图 重点
做到了拿到的数据 和 跳转到那个页面
业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该Spring MVC框架。
框架通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。
ModelAndView 的3种用法
- 1.ModelAndView的第一种用法,先创建ModelAndView对象,再通过它的方法去设置数据与转发的视图名
setViewName(String viewName):设置此 ModelAndView 的视图名称, 由 DispatcherServlet 通过 ViewResolver 解析 addObject(String attributeName, Object attributeValue):通过key/value的方式绑定数据 - 2.ModelAndView的第二种方法,可以直接通过带有参数的构造方法 ModelAndView(String viewName, String attributeName, Object attributeValue) 来返回数据与转发的视图名
return new ModelAndView(“m07”, “message”, “Hello World”);
- 3.ModelAndView的第三种用法,设置重定向
@Controller
@RequestMapping("/user")
public class TestController {
/**
* ModelAndView默认转发
* ModelAndView还是可以设置重定向
* 1. 重定向另一个控制器
* 2. 重定向具体的jsp页面
* @param name
* @return
* <a href="springmvc01/"小三"/m07">testPathVariable</a>
*/
@RequestMapping("/{name}/m07")
public ModelAndView m07(@PathVariable String name) {
if (!"admin".equals(name)) {
return new ModelAndView("redirect:/m07.jsp");
}
return new ModelAndView("m07");
}
}
映射URL绑定的占位符@PathVariable
-
带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有重大的意义.
- @PathVariable 注解可以将 URL 中占位符参数绑定到控制器处理方法的入参中;URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
//@PathVariable可以用来映射URL中的占位符到目标方法的参数中
abc.java
@RequestMapping("/lalala/{id}")
public String testPathVariable(@PathVariable("id") Integer id)
{
System.out.println("lalala:"+id);
return SUCCESS;
}
index.jsp
<a href="springmvc01/lalala/1">hahahah</a>
REST–表现层状态转化
- 资源(Resources)可以用一个URI(统一资源定位符)指向它.要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。
- 表现层(Representation)把资源具体呈现出来的形式
- 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。
- 具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
- https://blog.csdn.net/shuduti/article/details/53540142 来源
这里@RequestMapping的第一个用法表示此控制器上的所有处理方法都与/hello路径相关。 下一个注释@RequestMapping(method = RequestMethod.GET)用于声明printHello()方法作为控制器的默认服务方法来处理HTTP GET请求。
可以定义另一个方法来处理同一URL的任何POST请求。
可以以另一种形式在上面的控制器中编写,在@RequestMapping中添加其他属性,如下所示:
@Controller
public class HelloController{
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
/WEB-INF/hello/hello.jsp
<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
value属性指示处理程序方法映射到的URL,method属性定义处理HTTP GET请求的服务方法。关于以上定义的控制器,需要注意以下几点:
-
在服务方法中定义所需的业务逻辑。可以根据需要在此方法内调用其他方法。
-
基于定义的业务逻辑,将在此方法中创建一个模型。可以设置不同的模型属性,这些属性将被视图访问以呈现最终结果。此示例创建且有属性“message”的模型。
-
定义的服务方法可以返回一个String,它包含要用于渲染模型的视图的名称。此示例将“hello”返回为逻辑视图名称。
scr/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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置@Controller注解扫描 -->
<context:component-scan base-package="cn.atcast.controller"></context:component-scan>
<!-- 如果没有显示的配置处理器映射器和处理器适配那么springMvc会去默认的 dispatcherServlet.properties中查找,
对应的处理器映射器和处理器适配器去使用,这样每个请求都要扫描一次他的默认配置文件,效率非常低,会 降低访问速度,所以要显示的配置处理器映射器和 处理器适配器 然而 我们用了整合的<mvc>更为简洁-->
<!-- 注解驱动:作用:替我们 自动配置 最新版的注解的处理器映射器和处理器适配器-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器
作用:在controller中指定页面路径的时候就不用写页面的完整路径名称了,可以直接写页面去掉扩展名的名称
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 真正的页面路径 = 前缀 + 去掉后缀名的页面名称 + 后缀 -->
<!-- 前缀 prefix-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 后缀 suffix-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- InternalResourceViewResolver将定义用于解析视图名称的规则。根据上面定义的规则,hello的逻辑视图将委托给位于/WEB-INF/jsp/hello.jsp这个视图来实现。
三个核心的器
- 映射器 :解决请求要交给 那个action处理 [HandlerMapping] 找到所有拦截器
- 适配器 把请求真正的传给控制层
- 视图解析器
代码只见了一个器 是因为:
使用mvc:annotation-driven代替上边注解映射器和注解适配器配置器
<!-- 注解--映射器 寻找处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 注解---适配器 调用处理器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
大家好,我是凯凯!
大家看完觉得不错 请点个赞呗! 评论一句也可以! 整理不易, 请转发加我的名字哦!
你的支持 使我更有动力!