概述
Spring为展现层提供的基于MVC设计理念的优秀的Web框架,是目前最主流的MVC框架之一
SpringMVC通过一套MVC注解,使一个Java类成为处理请求的控制器,而无须实现任何接口
支持REST风格的URL请求
采用了松耦合可插拔组件结构,比其他的MVC框架更具扩展性和灵活性
一种轻量级的,基于MVC的web层应用框架,偏前端而不是基于业务逻辑层.Spring框架的一个后续产品
SpringMVC能做什么
- 天生与Spring框架集成
- 支持Restful风格
- 进行更简洁的Web层开发
- 支持灵活的URL到页面控制器的映射
- 非常容易与其他视图技术集成看,如:FreeMarker
- 因为模型数据不存放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用)
- 非常灵活的数据验证,格式验证,和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API
- 更加简单,强大的异常处理
- 对静态资源的支持
- 支持灵活的本地化,主题等解析
为什么要使用MVC
MVC(Model View Controller)是一种软件设计的框架模式,把数据处理、数据展示和程序/用户的交互三者分离开的一种编程模式
程序通过将M(Model)和V(View)的代码分离,实现类前后端代码的分离,带来的好处
- 可以使同一个程序使用不同的表现形式,如果控制器反馈给模型的数据发生了变化,那么模型将及时通知有关的视图,视图会对应的刷新自己所展现的内容
- 因为模型是独立于视图的,所以模型可复用,模型可以独立的移植到别的地方继续使用
- 前后端的代码分离,使项目开发的分工更加明确,程序的测试更加简便,提高开发效率
Spring MVC核心组件
-
DispatcherServlet : 前端控制器,把请求给转发到具体的控制类 (如果配置‘/’不包含 jsp)
-
Controller:具体处理请求的控制器
-
HandlerMapping:映射处理器,解析请求格式的.判断希望要执行哪个具体的方法
-
HandlerAdapter:负责调用具体的方法
-
ModelAndView:服务层返回的数据和视图层的封装类
-
ViewResolver:视图解析器,解析具体的视图
-
Interceptors :拦截器,负责拦截我们定义的请求然后做处理工作
-
MultipartResolver : 文件上传解析器
Spring容器和SpringMVC容器是 父子容器
SpringMVC 容器中能够调用 Spring 容器的所有内容
请求流程
- 用户向服务器发送请求,请求被SpringMVC前端控制器DispatcherServlet捕获
- 由DispatcherServlet控制器查一个或多个HandlerMapping,找到处理请求的Controller
- DispatcherServlet将请求提交到Controller(也称为Handler)
- Controller调用业务逻辑处理后,返回ModelAndView
- DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
- 视图负责将结果显示到客户端
Spring MVC注解
@RequestMapping
- SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求
- 在控制器的类定义及方法定义处都可以标注@RequestMapping
- 标记在类上 : 提供初步的请求映射信息,相对于 WEB应用的根目录
- 标记在方法上 : 提供进一步的细分映射信息,相对于标记在类上的URL
- 若类上未标注@RequestMapping,则方法出标记的URL相对于WEB应用的根目录
- 作用 : DispatcherServlet截获请求后,就通过控制器上@RequestMpping提供的映射信息定请求所对应的处理方法。
映射请求参数,请求方法或请求头
- @RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法,请求参数及请求头映射请求
- @RequestMapping的value【重点】、method【重点】、params【了解】 及 heads【了解】 分别表示请求 URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。
params 和 headers支持简单的表达式:- param1: 表示请求必须包含名为 param1 的请求参数
- !param1: 表示请求不能包含名为 param1 的请求参数
- param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
- {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
RequestMapping映射请求占位符PathVariable注解
@PathVariable
带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:
URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中
@ResponseBody
作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
@requestParam
@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 通过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。
@Controller
@Controller用于标记一个类,使用它标记的类就是一个Spring MVC Controller对象,即一个控制器类。Spring使用扫描机制查找应用程序中所有基于注解的控制器类。
分发处理器会扫描使用了改注解的类的方法,并检测该方法是否使用了@RequestMapping注解,而使用@RequestMapping注解的方法才是真正处理请求的处理器。
为了保证Spring能找到控制器,需要完成两件事情。:
- 在Spring MVC的配置文件的头文件中引入spring-context。
- 使用
<context:component-scan/>
元素,该元素的功能是:启动包扫描功能,以便注册带有 @Controller、@Service、@repository 、@Component 等注解的类成为Spring的Bean。base-package 属性制定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
REST
REST : Representational State Transfer(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用
RESTful架构风格的特点
资源
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。资源总要通过某种载体反应其内容,文本可以用txt格式表现,也可以用HTML格式、XML格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现;JSON是现在最常用的资源表示格式。
统一接口(Uniform Interface)
RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和delete,即数据的增删查改)操作,分别对应于HTTP方法:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,这样就统一了数据操作的接口,仅通过HTTP方法,就可以完成对数据的所有增删查改工作。
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
- PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
- DELETE(DELETE):从服务器删除资源。
HiddenHttpMethodFilter
浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。
配置HiddenHttpMethodFilter过滤器
<!-- 配置REST 过滤器 HiddenHttpMethodFilter
将满足转换条件的请求进行转换
1. 必须是post请求
2. 必须要通过_method能获取到一个请求参数值(要转换成的请求方式)-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
URI
可以用一个URI(统一资源定位符)指向资源,即每个URI都对应一个特定的资源。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或识别符。
一般的,每个资源至少有一个URI与之对应,最典型的URI即URL。
无状态
所谓无状态的,即所有的资源,都可以通过URI定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。有状态和无状态的区别,举个简单的例子说明一下。如查询员工的工资,如果查询工资是需要登录系统,进入查询工资的页面,执行相关操作后,获取工资的多少,则这种情况是有状态的,因为查询工资的每一步操作都依赖于前一步操作,只要前置操作不成功,后续操作就无法执行;如果输入一个url即可得到指定员工的工资,则这种情况是无状态的,因为获取工资不依赖于其他资源或状态,且这种情况下,员工工资是一个资源,由一个url与之对应,可以通过HTTP中的GET方法得到资源,这是典型的RESTful风格。
视图解析器
自定义视图解析器
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalR esourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
如果希望不执行自定义视图解析器,在方法返回值前面添加forward:或redirect:
文件上传
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
//文件的最大尺寸为5MB
<property name="maxUploadSize" value="5242880"></property>
//请求编码格式,必须和jsp的pageEncoding属性一致
<property name="defaultEncoding" value="utf-8"/>
</bean>
form表单的enctype一定要设置为multipart/form-data 二进制文件
需要基于apache的 commons-fileupload 和commons-io 两个 jar
MultiparResovlerzuoyong:
把客户端上传的文件流转换成MutipartFile封装类
通过MutipartFile封装类获取到文件流
表单数据类型分类
在<form>
的enctype属性控制表单类型
默认值:application/x-www-form-crlencoded,普通表单数据(少量文字信息)
text/plain:大量文字时使用的类型,邮件论文
multipart/form-data:表单中包含二进制文件内容
自定义拦截器
定义: Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
AOP: 在特定的方法前后扩充(针对ServiceImpl)
拦截器: 请求的拦截(只能是Controller)
Filter: 可以拦截任何请求
实现HandlerInterceptor接口
其中有三个方法:
preHandle(): 该方法会在控制器方法前执行,其返回值表示是否中断后续操作,当返回值为true时,继续向下执行;当返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行)
postHandle(): 该方法会在控制器方法调用之后,且解析视图之前执行,可以通过此方法对请求域中的模型和视图做出进一步的修改
afterCompletion(): 该方法会在整个请求完成,即视图渲染结束之后执行,可以通过此方法实现一些资源清理,记录日志信息等工作
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截器的作用路径 -->
<mvc:mapping path="/demo" />
<mvc:mapping path="/demo1" />
<mvc:mapping path="/demo2" />
<!-- 表示匹配指定路径的请求才进行拦截 -->
<bean class="cn.ljh.interceptor.DemoInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors>
元素用于配置一组拦截器
<bean>
定义的时全局拦截器,它会拦截所有的请求
<mvc:interrceptor>
元素定义的是指定路径的拦截器,会对指定路径下的请求生效,
<mvc:mapping>
用于配置拦截器作用的路径,该路径在其属性path中定义
如果在请求路径中包含不需要拦截的内容,可以通过<mvc:exclude-mapping>
元素进行配置
注:<mvc:interceptor>
中的子元素必须按照上述代码中的配置顺序进行编写,即<mvc:mapping>,<mvc:exclude-mapping>,<bean>
否则文件会报错
拦截器栈
多个拦截器同时生效时,组成拦截器栈
顺序: 先进后出
执行顺序和在springmvc.xml中配置顺序有关
设置先配置拦截器A在配置拦截器B执行顺序为
preHandle(A) -->preHandle(B) -->控制器方法 -->postHandle(B) --> postHanle(A) --> JSP --> afterCompletion(B) --> afterCompletion(A)