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 ...
随机推荐
- 基于MongoDB分布式存储进行MapReduce并行查询
中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询. ...
- alibaba笔试2
11. 12.C 13.C 14.C 关联:http://www.codingnow.com/2000/download/lua_manual.html 15.A
- sqlserver 2008 R2 分区表测试
有一张表期中有100多w条数据 程序执行起来比较慢,想用分区表的办法,使查询变快一些. 方案如下 --查看分区信息SELECT * FROM sys.partition_range_values -- ...
- MSP430F149流水灯闪烁以及数码管的显示
今天下午写了一个流水灯闪烁的实验,总的来说,不难,因为这块板子集合的电路图没有上一块那么复杂,所以总的来说,还是比较顺手,开始的时候,出现流水灯没有流转的现象,原来是没有加入延时函数,后来经过调整,结 ...
- algorithm: heap sort in python 算法导论 堆排序
An Python implementation of heap-sort based on the detailed algorithm description in Introduction to ...
- STL(pair map set vector priority_queue) poj 3297
POJ 3297 算法竞赛初级杂烩包 题意:学生选课,没个学生只能选一门课.大写字符是课的名字,小写是人名.如果课程后面有多个相同名字算一个,如果一个人选多门课,则他选不上课,输出课和每门课选课人数 ...
- Windows下ffmpeg的完美编译
纠结了好几天,终于搞定了,小结一下. 1.下载ffmpeg源码,官网 2.编译环境Msys的安装配置,http://blog.csdn.net/jszj/article/details/4028716 ...
- POJ1149 PIGS
想了好久啊...(#-.-) 开始想到m*n个点的构图,明显超时,于是考虑压缩节点个数 我们发现每个猪圈最后被有且只有一个人调整,于是想到对于一个人,连接他能调整的每个猪圈的上一个控制人.(不懂可以开 ...
- 基于Qt的P2P局域网聊天及文件传送软件设计
基于Qt的P2P局域网聊天及文件传送软件设计 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<通信网络>的课程设计作业,之 ...
- Uber将在泰国首推"优步摩托"服务
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...