Spring3之MVC
模式-视图-控制器(MVC)是UI设计中常见的设计模式, 该模式区分应用程序中的模式、视图和控制器三个角色,消除了业务逻辑与UI的耦合。模式负责封装视图展示的应用数据。视图应该只显示数据,不包含任何业务逻辑。控制器负责接受用户请求并调用后端服务进行业务逻辑。处理之后,后端服务可能返回某些数据供视图显示。控制器收集这些数据并准备视图的显示模式。MVC模式的核心思想是分离业务逻辑与UI,使它们能够独立修改,互不影响。
对与Web端的开发,从最开始的CGI,model1,以及现在的由model2演化而来的Web MVC模式, 逐渐形成这三个角色的概念,servlet作为控制器,模型采用javabean的形式,而视图展示,我们常见的是jsp页面。springmvc也是服务到工作者模式的实现,DispatchServlet作为前端控制器,由处理映射器HandlerMapping管理处理器,视图解析器进行视图的管理,其还提供了强大的约定大于配置的契约式编程支持。如下图所示:
DispatcherServlet被称为调度servlet,也是所谓的前端控制器,每个web请求都会经过它,比便使它能管理整个请求处理过程。如图当一个web用户发送请求,前端控制器收到请求将其委托给其他解析器,映射处理器HandlerMapping会将请求映射成HandlerExecutionChain对象,其找到特定的页面控制器controller,而后处理适配器HandlerAdapter调用controller内的功能方法完成处理,返回一个ModelAndView对象,视图解析器ViewResolver将这种逻辑视图名转换为特定的view,view再根据model的模型数据进行渲染,最后返回给前端控制器,由其响应用户。
我们知道web程序都会有个入口点,而springmvc的核心是DispatcherServlet,其实质上也是HttpServlet的子类,该servlet默认使用WebApplicationContext作为上下文,其会引导容器加载spring的配置信息,如图一般如下:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
我们也可以添加该servlet的参数配置,当然spring为我们提供了默认配置,contextClass默认使用XmlApplicationContext作为WebApplicationContext的接口,contextConfigLocation指定需要加载其他配置文件的地方,默认会在classpath里寻找[servletName]-servlet.xml的文件,我们可以自己contextConfigLocation里添加配置文件指定要添加的配置信息。
简单使用:我们进行springmvc进行web开发时,一般有两种方式。
我们可以自己实现Controller接口,然后自己编写我们自己的逻辑,然后这样会很复杂。我们可以根据的自己的需求实现和修改相应的类,下图展示类的层次结构:
如上图的各个类,现在该方式不推荐使用了。spring2.5之后增加了注解功能,spring3.0以后又丰富了注解的使用,该方法已成为事实上的标准了。
我们只需要简单地添加@Controlller,@RequestMapping等就可以指定相关的设置了,当然前提是我们需要使程序认得我们的设置,通过<context:component-scan>元素开启Spring的自动检测注解的组件扫描功能,还要在上下文中注册一个DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例处理@RequestMapping注解。如下:
<context:component-scan base-package="xxx.yyy.zzz"
use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<bean class="org.springframework.web.serlvet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
如果我们不开启组件扫描功能的话,需要在xml配置文件中,自己注入各个controller。上述配置的后两个bean,我们可以通过添加如下配置来替代他们:
<mvc:annotation-driven/>
使用注解的springmvc的controller的形式,大概如下:
@Controller
@RequestMapping("/welcome")
public class WelcomeController{
@RequestMapping(method=RequestMethod.GET)
public String welcome(Model model){
Date today = new Date();
model.addAttribute("today",today);
return "welcome";
}
}
我们也可以直接定义Mapping的格式为 @RequestMapping(value="/welcome",method=RequestMethod.GET)。剩下的我们再配置一个视图解析器就可以了,springmvc支持很多不同表现技术的视图,使用较多的是jsp模板。如下一个简单配置:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
请求映射,使用@RequestMapping注解,如下所示:
@RequestMapping("/member/add")
@RequestMapping(value={"/member/remove","/member/delete"},method=RequestMethod.GET)
@RequestMapping("/member/*") 这种一般配置Controller的。
@RequestMapping(“/member/display/{user}”) 其中user是要传入的变量,我们需要指定它如:@PathVariable("user") String user.这种方式以后传入的user变量都会代替user。
@RequestMapping(“/member/get”) 和 @RequestMapping(value="/member/get",method=RequestMethod.POST) 通过区分http不同的方法来定义不同的映射。
拦截器,拦截Web请求进行预先和事后处理, 我们可以为特定的URL映射注册处理程序拦截器,这样它只拦截映射到某些URL的请求。每个处理程序都要实现HandlerInterceptor接口,这个接口包含3个回调方法,preHandle(),postHandle(),afterCompletion()。最后一个方法是在所有请求处理完成之后(也就是显示视图之后)调用的。
如果我们实现了HandlerInterceptor接口的话,即使不需要全部方法也必须实现,因此我们可以使用继承HandlerInterceptorAdapter类来代替。这个类默认实现了所有拦截器犯法,与Java AWT的机制类似,我们需要覆盖哪个方法可以自己覆盖其内容就行了。可以将其配置和DefaultAnnotationHandlerMapping Bean放在一起就可以了。
视图解析器,我们可以在Web应用上下文声明一个或者多个视图解析器Bean,这些Bean必须实现ViewResolver接口,spring自带了很多解析器实现。
InternalResourceViewResolver 将利用前缀和后缀声明将每个视图名称映射到一个应用程序目录中。如下所示:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
这个解析器很简单,但是只能解析可内部资源视图,对于外部资源,可以它们声明为Bean,通过加载xml文件来解析的XmlViewResolver,默认加载/WEB-INF/views.xml,但是可以自己指定如:
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location">
<value>/WEB-INF/xxx-view.xml</value>
</property>
</bean>
spring还提供了从资源集中加载视图,这样利用资源集功能从不同的资源集加载用于不同区域的视图Bean。配置如下:
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
</bean>
指定了资源集文件名为views.properties,在资源集中我们可以自己定义哪个页面使用哪个解析器了。文件内容大概如下:
welcome.(class)=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
........
如果我们配置多个视图的话,还需要指定每个视图的优先级顺序,可通过order属性类设置,越低的顺序值代表越高的优先级。spring还提供了内容协商的视图策略,视图解析Bean为ContentNegotiatingViewResolver, 配置mediaTypes属性指定相应的视图解析器。
有时候我们需要导出Excel或者Pdf格式的文件,还需要配置特殊类型的视图解析器,SpringMVC支持Apache POI和JExcelAPI生成Excel文件,对应视图类为AbstractExcelView 和AbstractJExcelView, 支持iText程序库生成pdf文件,视图类是AbstractPdfView。
我们需要自己完成文件的创建过程,调用类库中的API编写我们自己的视图解析器类,可以使用ResourceBundleViewResolver解析器在properties文件中自定义视图解析类,还可同时使用视图内容协商方式。可在拦截器中添加文件的创建日期生成带时间的Excel或Pdf文件。
Spring还提供了标签和SpEL表达式语言,在此就不介绍了因为本人使用的少。
此外,spring还提供了区域解析器Locale resolver来识别用户区域,自带了多个该接口的实现,也可以自己创建一个区域解析器,可通过显示调用LocaleResolver.setLocale()来修改用户区域。如果我们不想为不同区域创建相同页面的不同版本,可以使用spring message来解析文本信息,jsp中使用<spring:messsage>标记来实现。spring还提供了对异常视图的解析,解析器Bean须实现HandlerExceptionResolver接口。而对于文件上传,spring提供了MultipartResolver接口,可以使用CommonsMultipartResolver,其使用Commons FileUpload类库实现。
下面介绍Springmvc常见注解及一些新特性 :
@Controller:用于标识是处理器类;
JSR-303验证框架的无缝支持(通过@Valid注解定义验证元数据);
最好的指南是spring本身的文档,建议多看看文档!
Spring3之MVC的更多相关文章
- Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码)
Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码) 备注: 之前在Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合中 ...
- [转]基于全注解的Spring3.1 mvc、myBatis3.1、Mysql的轻量级项目
摘要 对于现在主流的j2ee企业级开发而言,ssh(struts+hibernate+spring)依然是一个事实的标准.由struts充当的mvc调度控制:hibernate的orm持久化映射:sp ...
- Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合
项目环境背景: 操作系统:win7 JDK:1.7 相关依赖包,截图如下:
- spring MVC之返回JSON数据(Spring3.0 MVC)
方式一:使用ModelAndView的contentType是"application/json" 方式二:返回String的 contentType是&qu ...
- Spring3 MVC使用@ResponseBody的乱码问题及解决办法
近日用Spring3的MVC写东西,深感其之于Webwork/Struts2的便利,但是在通过@ResponseBody这个annotation输出一个json字符串的时候,发现页面上获得的json字 ...
- 基于spring mvc的注解DEMO完整例子
弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件.本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mv ...
- Spring MVC体系结构
[Spring MVC类图]<Spring实战>中:<Spring3.0就这么简单>中:[http://blog.csdn.net/gstormspire/article/de ...
- Spring MVC 注解[转]
[学习笔记]基于注解的spring3.0.x MVC学习笔记(九) 摘要: 本章节,仅为@SessionAttributes的功能扩展介绍介绍,结合@requestparam注解进行简易无数据库分页. ...
- spring MVC做form提交Neither BindingResult nor plain target object for bean name 'command' available
这两天在做spring3.0 MVC+hibernate3.2的练习中,做简单的form提交, 一直报java.lang.IllegalStateException: Neither BindingR ...
随机推荐
- Base-Android快速开发框架(三)--数据存储之SQLite
SQLite,是一款轻量级的关系型数据库,Android原生集成的一个数据库.具有轻量级.独立性.隔离性.安全性等特点.是Android做数据存储的必备知识之一. 在实际的项目中,我们常用于一些对象的 ...
- Makefile编程
[个人体会]0.1 项目文件要合理分隔,功能模块分开放,分别设置Makefile自动编译, 0.2 源码和头文件分开放,一个或多个头文件对应一个源码文件. ...
- 转载:MATLAB画图常用调整代码
%单y轴 plot(t*1e+,abs(iGG)/max(abs(iGG)),); axis([-,,,]) xlabel('时间/ns'); ylabel('幅度/a.u.'); ,'FontNam ...
- eclipse配置struts.xml自动提示
a)window – preferences – xml - xml catalog –> add b)选择key type为URI c)key: http://struts.apache.o ...
- Jquery Form表单元素对象化
function serializeObject(form){ var o = {}; $.each(form.serializeArray(),function(index){ o[this['na ...
- A Tour of Go Switch
You probably knew what switch was going to look like. A case body breaks automatically, unless it en ...
- Java & XML Tutorial
Java comes with a set of tools to process XML. These Java XML tools are: SAX Parser StAX Parser DOM ...
- rxjs5.X系列 —— Combination/Multicasting系列 api 笔记
欢迎指导与讨论 :) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第三篇 -- Combination组合与Multicasting广播.如有错漏,希望大家指出提醒O ...
- 菜单设计器(Menu Designer)及其B/S,C/S双重实现(B/S开源)
ERP/MIS开发 菜单设计器(Menu Designer)及其B/S,C/S双重实现(B/S开源) 一直从事ERP/MIS的开发工作,今天来展现一下菜单设计器的设计,及其用途,并对B/S部分代码 ...
- xcode中create groups 和 create folder reference 的区别
(文章为博主原创,未经允许,不得转载!) 今天在项目中搭建框架忽然发现工程中有黄蓝文件夹的区别,而且对应到不同的情况: 1.蓝色文件夹下文件不能被读取: 2.蓝色文件夹下创建新的文件类会直接跳过选择类 ...