`
iwebcode
  • 浏览: 2012956 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

MVC

 
阅读更多

MVC与WEB应用

MVC是什么就不用我多说了.对于现有较成熟的Model-View-Control(MVC)框架而言,其注意的主要问题无外乎下面这些:

Model:

模型应该包含由视图显示的数据.在J2EE Web应用中,数据通常应该由普通的javabean组成.一旦一个控制器选择了视图,模型就要包含视图相应的数据.模型本身不应该进一步的访问数据,也不应该和业务对象相联系.

模型要解决的问题包括:

l封装要显示的数据

l我不认为模型要依赖于特定的框架

l不一定非得是javabean

View:

视图负责显示出模型包含的信息,视图不必了解控制器或是底层业务对象的具体实现

视图要解决的问题包括:

l在显示给定数据模型的情况下显示内容

l不应该包含有业务逻辑

l可能需要执行显示逻辑,比如颜色交替的显示某个数组的各行

l视图最好不处理验证的错误,数据的验证应该在由其他组件完成

l视图不应该处理参数,参数应该交由控制器集中处理

Control:

控制器就好像MVC里的中枢神经,它也许会需要一些助手来帮助它比如解析视图,解析参数等.控制器可以访问到业务对象或者是它的代理是很重要的,比如Struts里的Action.

控制器要解决的问题包括:

l检查和抽取请求参数

l调用业务对象,传递从请求中获取的参数

l创建模型,视图讲显示对应的模型

l选择一个合适的视图发送给客户端

l控制器有时不会只有一个

现有的框架

现在已经有很多的MVC的框架实现.比较流行的应该就是Struts和Webwork了

Struts

这是最流行的web框架,几乎成为了实际上的工业标准.除了上面讨论的MVC模式应该有的优点以外.它还有如下一些缺点:

l每个Action只生成一次,然后就被缓存起来,再次请求这个Action的时候就不会生成新的对象,而是重复使用第一次生成的对象,这就意味着每个Action必须是线程安全的

l采用ActionForm封装了表单数据,但是却只能对应String类型的数据,虽然它可以使用工具Commons Beanutils进行类型转化,但是仅仅是提供了对象级别的支持

l严重的依赖于Servlet API,测试比较困难(不过下一版Struts里的Action.execute的方法签名讲会换成execute(ActionContext actionContext),依赖也许不会那么严重)

l框架本身的验证规则比较简单,一般都是依赖于Commons Validation进行验证

l想在Action前后做些处理很困难.有时甚至不得不自己去写专门的控制器

l由于Struts都是具体的类继承,这样很容易打破封装?

l提供各式各样的自定义的标签,但是数据绑定太原始了,这样就使页面代码依赖于Struts这个特定的框架,而它却不是规范,我觉得这是很致命的

l它太面向JSP了,尽管使用其他视图技术是有可能的,但是使用的时候却不是很方便

Webwork

这个框架虽然我没使用过,但是却一直在关注它的发展

Webwork的设计思想采用了比Struts更为聪明的一种方式,就技术角度上说比Struts要高出不少.它以Command模式为基础.分为Xwork和Webwork,而且框架并不依赖于Servlet API.

Xwork提供了很多核心功能:拦截器(Interceptor),运行时表单验证,类型转换,IoC容器等.

WebWork建立在Xwork之上,用于处理基于HTTP的响应和请求.用Map和ActionContext封装了Session,Application等这些Servlet对象.从而解除了和Servlet API的耦合.

但是它仍然不是完美的:

l为每一个请求都创建一个Action可能有些浪费.(但是Servlet引擎也是为每个请求创建多个对象,但是也没看出来对性能有多大的影响?)

l当项目越来越大的时候,配置文件可能会很零乱.好像它不支持多个配置文件

l异常处理是Command模式里值得注意的问题:我们不知道某一特定命令可能会抛出什么特定的异常,所以execute()被迫抛出异常,而不论异常是运行时异常,还是已检查异常

Spring MVC Framework的目标

上面说了一些MVC的原理,以及现在主流框架的一些问题,现在来看Spring是如何处理的. Spring MVC框架根据不同的角色定义了很多接口,但是它最大的问题也是依赖于Servlet API

Spring MVC Framework有这样一些特点:

l它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成.

l不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)

l可以任意使用各种视图技术,而不仅仅局限于JSP

l支持各种请求资源的映射策略

l它应是易于扩展的

我认为评价一个框架,应该有几个原则

l它应该是易于使用的,易于测试的

Spring易于使用吗?我不这么觉得,尤其是它的配置文件.在最恐怖的情况下,各种业务逻辑,基础设施也许会拥挤在一个配置文件里.而如事务处理这些基础设施应该是由容器管理而不是开发人员,就算把这些分开到几个配置文件里,逻辑上虽然清晰了,但是基础设置却还是暴露在外边

Spring易于测试吗?对Spring进行单元测试很容易,测试起来很方便

l应该在多个层次上提供接口

Spring提供了很多接口,而几乎每个接口都有默认的抽象实现,每个抽象实现都有一些具体实现,所以在可扩展性这点上Spring无疑是很优秀的

l框架内部和框架外部应该被区别对待

框架内部可以很复杂,但是使用起来一定要简单,Spring的内部比较麻烦,但是它很好的隐藏了这种复杂性,使用起来很舒服,比如设置一个bean的属性.仅仅是setPropertyValue(StringpropertyName, Objectvalue)就完成,至于怎么去设置,Spring完全隐藏了这种复杂性

l完善的文档和测试集

这个就不用说了,老外的东西,都很完善

Spring Web框架基本流程

知道了Spring MVC框架,现在来看看它的流程

Spring MVC Framework大至流程如下:

当web程序启动的时候,ContextLoaderServlet会把对应的配置文件信息读取出来,通过注射去初始化控制器DispatchServlet.而当接受到一个HTTP请求的时候, DispatchServlet会让HandlerMapping去处理这个请求.HandlerMapping根据请求URL(不一定非要是URL,完全可以自定义,非常灵活)来选择一个Controller.然后DispatchServlet会在调用选定的Controller的handlerRequest方法,并且在这个方法前后调用这个Controller的interceptor(假如有配置的话),然后返回一个视图和模型的集合ModelAndView.框架通过ViewResolver来解析视图并且返回一个View对象,最后调用View的render方法返回到客户端

DispatcherServlet

这是框架的控制器,是一个具体类,它通过运行时的上下文对象来初始化.控制器本身并不去控制流程,而只是是Controller的”控制器”,他只是把处理请求的责任委托给了对应的Controller.

控制器继承自抽象基类FrameworkServlet,它的属性webApplicationContext就代表着这个web程序上下文,而这个上下文对象默认实现就是从一个XML文件读取配置信息(当然也可以是其他文件格式). WebApplicationContext其实是beans包的东西,这个包提供了这个Spring整个框架的基础结构,以后我会分析这个包的内容.但是现在仅仅需要知道WebApplicationContext代表一个web应用的上下文对象.

现在来看看DispatchServlet是如何工作的:

DispatchServlet由于继承自抽象基类FrameworkServlet,而FrameworkServlet里的doGet(),doPost()方法里有调用serviceWrapper(),跳到serviceWrapper()里去看,结果发现它有把具体实现委托给了doService(request, response);方法.所以现在已经很清楚了, DispatchServlet真正实现功能的是doService()这个方法.

特别的, FrameworkServlet的initFrameworkServlet()这个方法是控制器的初始化方法,用来初始化HandlerMappings之类的对象,这也是延迟到子类实现的.其实就是一个Template模式的实现.don’t call us, we will call u.总的看来,Spring就是通过这样来实现它的控制反转的:用框架来控制流程,而不是用户

跳到doService()一看究竟,就会发现真正工作的又是另一个助手函数doDispatch(request, response),没办法,继续看下去,发现这样两行代码

HandlerExecutionChain mappedHandler = null;

mappedHandler = getHandler(processedRequest, false);

看HandlerExecutionChain源码就发现它其实就是对Controller和它的Interceptors的进行了包装;

getHandler()就是从HandlerMappings(这是一个List,存放的handlerMapping对象)中取出对应的handlerMapping对象,每个HandlerMapping对象代表一个Controller和URL的映射(其实在运行的时候是一个HandlerExecutionChain和URL的映射,而HandlerExecutionChain对象其实就是对Controller和它interceptors的一个包装器,可以把HandlerMapping看成Controller和URL的映射).而这个HandlerMapping是通过配置文件在运行时注射进来的,一般是SimpleUrlHandlerMapping这个子类

取得了HandlerMapping对象,继续向下看,发现:

if (mappedHandler.getInterceptors() != null) {

for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {

HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];

if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {

triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);

return;

}

interceptorIndex = i;

}

}

这里就是在调用Controller的拦截器,原理就是这句了:

interceptor.preHandle(processedRequest, response, mappedHandler.getHandler(), mv);

preHandle方法传入了mappedHandler.getHandler()这个参数来实现递归调用!而interceptor.postHandle方法如此一般.只不过这个方法是在handleRequest方法后调用

继续看下去:

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

发现Controller的handleRequest真正的操作又被代理给了HandlerAdapter的handle方法,并且返回一个ModelAndView,我想这里增加一层的意义应该是为了解除Controller和DispatchServlet的耦合吧.

接着就很简单了,调用render()方法,在这个方法里面由ViewResoler解析出视图名,再调用视图对象的render方法把合适的视图展现给用户

到此,控制器的流程就OVER了

HandlerMapping

通过使用HandlerMapping,控制器可以用URL和某一个Controller进行标准的映射,而实现URL映射的具体子类的UrlHandlerMapping.

Spring还允许我们自定义映射,比如通过Session,cookie或者用户状态来映射.而这一切仅仅只需要实现HandlerMapping接口而已.不过URL映射已经能满足大部分的要求

Controller

Controller类似Structs的Action, Controller接口只有一个方法handleRequest(),放回一个ModelAndView对象,如同设计目标所说的那样,每个Controller都是一个java组件,所以它可以在上下文环境中任意配置,组件属性都会在初始化的时候被配置.Spring自己提供了几个具体的实现.方便我们使用

ViewResolver

Controller通常返回包含视图名字而不是视图对象的ModelAndView对象.从而彻底的解除了控制器和视图之间的耦合关系,并且在这里还可以提供国际化的支持.

在你的配置文件中你可以:

welcomeView.class = org.springframework.web.servlet.view. InternalResourceView

welcomeView.url=/welcome.jsp

也可以

welcomeView.class = org.springframework.web.servlet.view.xslt. XsltView

welcomeView.url=/xslt/default.xslt

View

这也是一个java组件,它不做任何请求处理或是业务逻辑,它仅仅获取模型传递的数据,并把数据显示出来.它里面的render方法按照如下流程工作:

l设置模型的数据到request作用域

l取得视图的URL

l转发到对应的URL

分享到:
评论

相关推荐

    ASP.NET MVC项目实例

    ASP.NET MVC作为微软官方的.NET平台下MVC解决方案,自诞生起就吸引了众多.NET平台开发人员的眼球。ASP.NET MVC从一开始的设计思路就与Struts不同,它的映射是利用路由配置而非xml,从而大大降低了开发复杂度,并且比...

    精通Spring MVC 4

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring...

    ASP.NET MVC企业实战源代码Chapter12.rar

    本书共分为12章,以符合初学者思维的方式系统地介绍ASP.NET MVC的应用技巧,并结合实际项目详细地介绍如何基于ASP.NET MVC构建企业项目。通过本书的学习,读者可以全面掌握ASP.NET MVC的开发,并从代码中获取软件...

    【免费】ASP.NET MVC5 高级编程[附源码].rar

    ASP.NET MVC5高级编程(第5版.NET开发经典名著)作为Microsoft备受欢迎的MVC技术的最新版本,MVC 5是一个成熟的Web应用程序框架,支持快速的、TDD友好的开发。MVC允许开发人员创建动态的、数据驱动的网站。这样的...

    ASP.NETMVC5网站开发之美【高清PDF】

    第1章 MVC概述 第2章 与数据的对话:Model与ADO.NET 第3章 LINQ:驱动数据的查询功能 第4章 EF 第5章 路由(Routing) 第6章 控制器(Controller) 第7章 异步程序设计 第8章 View:摇曳生姿的美人 第9章 Bootstrap ...

    Pro ASP.NET MVC 5 Platform(Apress,Adam.Freeman,2014)

    The power of ASP.NET MVC 5 stems from the underlying ASP.NET platform. To make your ASP.NET MVC applications the best they can be, you need to fully understand the platform features and know how they ...

    JavaWeb基于MVC模式开发的简易购物车系统

    该系统主要采用MVC(JSP+JavaBean+Servlet)模式开发,非常适合初学者了解并掌握MVC开发模式,具有如下主要功能: 1.用户登录,注册(用户注册后才能登录) 2.显示所有书籍基本信息(编号,书名,价格等) 3.添加...

    基于ASP.NET MVC项目源码完整下载(含Aspose.Cells、Aspose.Words、NPOI、MvcPaper及在线预览Word、Excel等文档

    基于ASP.NET MVC框架的学习项目,包含MVC的框架的设计思路,通俗易懂学习MVC框架,项目中包含NPOI控件的使用方法(优点:导出几万条数据几秒即可下载下来)以及NPOI导出Excel表到数据库,Aspose.Cells的使用(导入、...

    Programming Microsoft ASP.NET MVC, 3rd Edition

    Develop next-generation web applications with ASP.NET MVC Go deep into the architecture and features of ASP.NET MVC 5, and learn how to build web applications that work well on both the desktop and ...

    ASP.NET MVC实战

    《ASP.NET MVC实战》适合于对MVC框架感兴趣的ASP.NET开发人员,其中的许多设计原则和最佳实践则可以适合于各种开发人员。MVC作为一种流行的应用程序开发框架已经存在多年。现在,Microsoft公司也加入了这个社区,ASP...

    MVC国际化,MVC多语言,.NET多语言

    MVC国际化,MVC多语言,.NET多语言 中英文切换

    Aspnet Mvc教程 11.重定向、Redirect

    Aspnet Mvc教程 1.说明 01:06 Aspnet Mvc教程 2.准备工作 02:37 Aspnet Mvc教程 3. 建立并运行 02:46 Aspnet Mvc教程 4.默认程序结构 04:18 Aspnet Mvc教程 5. 基本工作流程 05:13 Aspnet Mvc教程 6.mvc理论讲解...

    Aspnet Mvc教程 5. 基本工作流程

    Aspnet Mvc教程 1.说明 01:06 Aspnet Mvc教程 2.准备工作 02:37 Aspnet Mvc教程 3. 建立并运行 02:46 Aspnet Mvc教程 4.默认程序结构 04:18 Aspnet Mvc教程 5. 基本工作流程 05:13 Aspnet Mvc教程 6.mvc理论讲解...

    经典MVC登录实例代码

    mvc入门——经典MVC登录实例

    MVC架构(模式)

    主要包括MVC的设计思想、实现和原理,以及和其他人的理解。 一、MVC设计思想 二、MVC设计模式的实现 三、MVC设计模式的扩展 四、MVC的优点 五、MVC的不足

    mvc3,4,5区别于联系

    mvc3.mvc4/mvc5区别于联系,1.use new features like 'Tilde slash'. 2.Syntex:Razor Syntax and 'Tilde Slash'i.e 3.Chart,WebGrid,Crypto,WebImage,WebMail Controls 4.ViewBag is not onle available but it is ...

    Asp.net MVC快速开发框架源码 mvc+Bootstrap

    Asp.net MVC快速开发框架源码 mvc+Bootstrap 框架使用场景:OA、ERP、BPM、CRM、WMS、TMS、MIS等业务管理系统及后台系统

    vue项目demo(asp.net mvc5+vue2.5)

    本项目是asp.net mvc5+vue2.5的项目,花了很长时间做的。 实现的功能如下: 1.不仅有vue的基本功能,而且设计到vue的组件功能。 2.实现了增删改查的功能,而且是一对多的。 3.后台使用了EF进行操作数据库,EF使用的...

    mvc框架性比较

    对目前主力mvc框架进行性能比价,包括struts,spring mvc等

    MVC 微软范例源码

    MVC微软范例源码,MVC music项目源码

Global site tag (gtag.js) - Google Analytics