SpringMVC
1:什么是MVC
MVC(Model View Controller)是一种软件设计的框架模式,它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离。把众多的业务逻辑聚集到一个部件里面,当然这种比较官方的解释是不能让我们足够清晰的理解什么是MVC的。用通俗的话来讲,MVC的理念就是把数据处理、数据展示(界面)和程序/用户的交互三者分离开的一种编程模式。 注意!MVC不是设计模式!
MVC框架模式是一种复合模式,MVC的三个核心部件分别是
1:Model(模型):所有的用户数据、状态以及程序逻辑,独立于视图和控制器
2:View(视图):呈现模型,类似于Web程序中的界面,视图会从模型中拿到需要展现的状态以及数据,对于相同的数据可以有多种不同的显示形式(视图)
3:Controller(控制器):负责获取用户的输入信息,进行解析并反馈给模型,通常情况下一个视图具有一个控制器
1.2:为什么要使用MVC
程序通过将M(Model)和V(View)的代码分离,实现了前后端代码的分离,会带来几个好处
1:可以使同一个程序使用不同的表现形式,如果控制器反馈给模型的数据发生了变化,那么模型将及时通知有关的视图,视图会对应的刷新自己所展现的内容
2:因为模型是独立于视图的,所以模型可复用,模型可以独立的移植到别的地方继续使用
3:前后端的代码分离,使项目开发的分工更加明确,程序的测试更加简便,提高开发效率
下图是MVC的各个组件之间的关系以及功能图
其实控制器的功能类似于一个中转站,会决定调用那个模型去处理用户请求以及调用哪个视图去呈现给用户
1.3:JavaWeb中MVC模式的应用
在JavaWeb程序中,MVC框架模式是经常用到的,举一个Web程序的结构可以更好的理解MVC的理念
V:View视图,Web程序中指用户可以看到的并可以与之进行数据交互的界面,比如一个Html网页界面,或者某些客户端的界面,在前面讲过,MVC可以为程序处理很多不同的视图,用户在视图中进行输出数据以及一系列操作,注意:视图中不会发生数据的处理操作。
M:Model模型:进行所有数据的处理工作,模型返回的数据是中立的,和数据格式无关,一个模型可以为多个视图来提供数据,所以模型的代码重复性比较低
C:Controller控制器:负责接受用户的输入,并且调用模型和视图去完成用户的需求,控制器不会输出也不会做出任何处理,只会接受请求并调用模型构件去处理用户的请求,然后在确定用哪个视图去显示返回的数据
1.4:Web程序中MVC模式的优点
耦合性低:视图(页面)和业务层(数据处理)分离,一个应用的业务流程或者业务规则的改变只需要改动MVC中的模型即可,不会影响到控制器与视图 部署快,成本低:MVC使开发和维护用户接口的技术含量降低。使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上
可维护性高:分离视图层和业务逻辑层也使得WEB应用更易于维护和修改
1.5:Web程序中MVC模式的缺点
调试困难:因为模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难,每个构件在使用之前都需要经过彻底的测试
不适合小型,中等规模的应用程序:在一个中小型的应用程序中,强制性的使用MVC进行开发,往往会花费大量时间,并且不能体现MVC的优势,同时会使开发变得繁琐
增加系统结构和实现的复杂性:对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率
视图与控制器间的过于紧密的连接并且降低了视图对模型数据的访问:视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能
2、Spring MVC框架
现在MVC框架已经有很多了,Struts、Webwork,新兴的MVC框架有Spring MVC、JSF等等,本文主要介绍Spring MVC的设计理念。
Struts1.0是基于webwork的MVC框架,里面有很多类的继承关系,耦合性太高,之后推出了struts2.0,但是这个MVC框架对于视图的解析还是存在一些小的不妥之处,而且还有安全漏洞,所以产生了Spring MVC
2.2、Spring MVC介绍
Spring MVC采用了松散耦合的可插拔组件结构,比其他的MVC框架更具有灵活性和扩展性,Spring MVC通过使用一套注解,使一个Java类成为前端控制(Controller),不需要实现任何接口,同时,Spring MVC支持RES形式的URL请求,除此之外,Spring MVC在在数据绑定、视图解析、本地化处理及静态资源处理上都有许多不俗的表现。
Spring MVC围绕DispatcherServlet(前端控制器)为中心展开,DispatcherServlet(前端控制器)是Spring MVC的中枢,和MVC的思想一样,它负责从视图获取用户请求并且分派给相应的处理器处理,并决定用哪个视图去把数据呈现给给用户
2.3、Spring MVC特点
1:让我们能非常简单的设计出干净的Web层和薄薄的Web层;
2:进行更简洁的Web层的开发;
3:天生与Spring框架集成(如IoC容器、AOP等);
4:提供强大的约定大于配置的契约式编程支持;
5:能简单的进行Web层的单元测试;
6:支持灵活的URL到页面控制器的映射;
7:非常容易与其它视图技术集成,如Velocity、FreeMarker等,因为模型数据不放在特定的API里,而是放在一 个Model里(Map数据结构实现,因此很容易被其他框架使用); 8:非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API;
9:提供一套强大的JSP标签库,简化JSP开发;
10:支持灵活的本地化、主题等解析;
11:更加简单的异常处理;
12:对静态资源的支持; 支持Restful风格。
2.3、Spring MVC流程图
在Spring MVC框架中,每个DispatcherServlet都有其自有的WebApplicationContext,它会继承在root WebApplicationContext中定义的beans。 root WebApplicationContext应该包含所有基础beans,以被其他contexts 和 Servlet实例分享。被继承的beans可以被特定Servlet scope重写,你可以定义针对给定Servlet实例(其scope)的beans。
在DispatcherServlet初始化过程中,Spring MVC会在web应用的/WEB-INF文件夹下查找名字为 [servlet-name]-servlet.xml 的文件,创建其中定义的bean,并会重写在全局scope中已经定义的任何beans的定义。
2.4、Spring MVC的注解
@Controller:写在controller层类上,代表表明这是一个控制器类。
@ResponseBody:可以写在controller层类上以及方法上,代表放回的是JSON数据,过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,如果没有放回的就是跳转路径的url。
@RestController:等于controller+ResponseBody,代表表明这是一个控制器类,并且这个类中方法全部返回JSON数据。
@RequestBody:写在类中方法形参前,该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上; 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。
@RequestMapping:写在类上或者方法上,用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法,此处需注意@RequestMapping用在类上可以没用,但是用在方法上必须有,而且默认是get请求。
2.4、Spring MVC的请求流程
整体流程:Request -> Handler -> 执行结果 -> 返回(REST) -> 普通的文本
请求处理映射:RequestMappingHandlerMapping -> @RequestMapping Handler Mapping
HandlerMapping ,寻找Request URI,找到匹配的 Handler ,执行当前的处理,把结果放回,并通过浏览器显示给用户。
Handler:处理的方法,当然这是一种实例
2.5、拦截器:HandlerInterceptor
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间。
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。
处理顺序:preHandle(true) -> Handler: HandlerMethod 执行(Method#invoke) -> postHandle -> afterCompletion
preHandle(false)->后面的都不会走,到这里截止返回
2.6、Spring MVC异常处理
传统的Servlet web.xml 错误页面
* 优点:统一处理,业界标准
* 不足:灵活度不够,只能定义 web.xml文件里面
<error-page> 处理逻辑:
* 处理状态码 <error-code>
* 处理异常类型 <exception-type>
* 处理服务:<location>
Spring Web MVC 异常处理
* @ExceptionHandler
* 优点:易于理解,尤其是全局异常处理
* 不足:很难完全掌握所有的异常类型
两种拦截方式
* @RestControllerAdvice = @ControllerAdvice + @ResponseBody
* @ControllerAdvice 专门拦截(AOP),是组件注解,他使得其实现类能够被classpath扫描自动发现,拦截 @Controller
Spring Boot 错误处理页面
* 实现 ErrorPageRegistrar
* 状态码:比较通用,不需要理解Spring WebMVC 异常体系
* 不足:页面处理的路径必须固定
* 注册 ErrorPage 对象
* 实现 ErrorPage 对象中的Path 路径Web服务
2.7、Spring MVC的国际化
1.基于Session的国际化实现
2.基于Cookie的国际化实现
3.基于拼接url的国际化实现: