Web MVC框架(PART1)

Spring Web MVC 框架介绍

Spring Web MVC框架是围绕着DispatchServlet设计的,DispatchServlet负责将web请求分发到handlers,在这个分发过程中包括可配置的handler映射,视图处理,本地化,时区及主题和文件上传。默认情况的handler是基于@Controller和@RequestMapping两种注释,提供了灵活的处理方法。在Spring3.0之后,@Controller机制同样允许创建Restful的网络站点和应用,通过@PathVariable注释以及其它的特性。

面向拓展是Spring Web MVC的核心原则,Spring的原则是”Open for extension,closed for modification“。

在Spring Web MVC中一些核心类被标记为”final“。由于开发者无法对这些方法进行重写。

针对这个原则的解释在Expert Spring Web MVC中有比较详细的解释。另外在Bob Martin的文章”The Open-Closed Principle(PDF)“中也有解释。

在使用Spring MVC时不能针对final方法添加切面。比如,不能够对AbstractController.setSynchronizedOnSession()添加切面。在”Understandding AOP proxies“有针对AOP代理以及为何不能添加切面的原因。

在Spring Web MVC中,你可以使用任何对象作为命令或表单后台对象,你不需要去实现框架特定的接口或者基类。Spring的数据绑定非常灵活。例如Spring中将类型不匹配视为验证失败而不是系统错误。因此不需要将业务对象复制为表对象中无类型的字符串来处理无效的提交,或者将字符串转化为业务对象。因此将业务对象直接和表对象绑定更加方便。

Spring的视图处理也非常灵活。Controller一般用来映射处理数据和视图,当然它可以直接用来应答流并完成请求。视图名称处理可以通过文件拓展或者通过bean名称甚至自定义的ViewResolverl实现的接受头文件类型协议来完成。MVC中的M指的是映射接口,此接口代表了视图技术的完整抽象。可以和常见视图模板茹JSP、Velocity和FreeMarker记性集成,甚至直接生成XML、JSON、Atom以及气态的多种内容类型。Map可以简单的转化成正确的类型,例如JSP的请求类型,Velocity的模板等。

Spring Web MVC的特点

Spring的网络模块包括许多独特的网络支持特性:

1)清晰的角色分层。控制器、验证器、命令对象、表单对象、模型对象、DispatchServlet、处理映射,视图方案。

2)强大直观的框架和应用类JavaBean的配置,配置包括能够简单的在上下文中引用,例如表单网络控制器到业务对象和验证器。

3)适配性、非入侵性、灵活性。可以定义任意的Controller方法,并通过参数注解(如@RequestParam、@RequestHeader、@PathVariable)

4)可复用的业务代码,不需要冗余业务代码。使用业务对象作为命令或者表单对象而不需要通过扩展框架基类实现。

5)可定制的绑定和验证。类型不一致被作为应用层的验证错误,从而不需要人工进行类型解析和转换来判断数据错误。

6)自定义的handler映射和视图处理。handler映射和视图处理策略包括简单的URL配置到复杂的特定目的地策略。Spring相比web MVC在集成技术上更加灵活。

7)简单强大的JSP标签库,可以方便的进行数据绑定和主题设置。自定义的标签可以灵活的使用标签代码。

8)Bean的整个生命周期包含当前的HTTP请求或者HTTP会话中。这并非是Spring MVC本身的特性,而是Spring实用的WebApplicationContext容器的特新。

其他MVC实现的即插即用

在一些工程中,非Spring的MVC实现可能更加合适。许多团队需要来综合评估他们当前的技术和工具积累,例如JSF。

如果不想使用Spring WebMVC,而是希望能够使用Spring其它的功能,你可以将Spring集成到先用的web MVC中。通过使用ContextLoaderListener来开启Spring的根应用,并通过ServletContext属性来访问一些特性。此时,从web层面上看,仅仅是将Spring作为类库,将Spring的根应用上下文作为入口。

DispatcherServlet

Spring的web MVC框架和其它的需要MVC框架一样,都是基于请求驱动,并围绕着核心的分发到控制器和其它功能Servlet设计的。Spring的DispatcherServlet可以做的比这跟多。它能够完全的集成Spring的控制反转从而允许使用Spring的所有特性。

Spring Web MVC的DispatcherServlet的处理步骤在下图中展示。模式识别会将DispatcherServlet理解为前端控制器的表达式(这是Spring Web MVC和其它大多数热门网络框架共同具有的模式)。

Spring Web MVC workflow

DispatcherServlet是继承自HttpServlet的。为了使用DispatcherServlet需要将请求映射到的对应的handler上。下面是标准的JAVA EE Servlet的标准配置。

```

public class MyWebApplicationInitializer implements WebApplicationInitializer{

@override

public void onStartup(ServletContext container){

ServeletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());

registration.setLoadOnStartup(1);

registration.addMapping("/example/");

}

}

```

在前面的例子中,所有的请求都是以/example开始的,对应的请求都会被DispatcherServlet处理。WebApplicationInitializer是Spring MVC提供的接口,它可以保证基于代码的配置能够被识别并且能够自动的被Servlet容器初始化。有一个这种接口的抽象基类实现叫做AbstractAnnotationConfigDispatcherServletInitializer,它能够让注册DispatcherServ更加容易,比如见到你的通过制定Servlet映射和列出配置类。这其实是Spring MVC 应用的推荐模式。(还有一种叫做基于代码的Servlet容器初始化)

DispatcherServlet是继承与HttpServlet的Servlet,因此它会在web.xml中被声明。为了让dispatcherServlet工作,需要在web.xml中使用URL映射。下面是典型的JAVA EE的Servlet的配置,下面的例子展示了DispatchServlet的声明和映射。

下面的web.xml展示了上面的例子。

```

<web-app>

<servlet>

<servlet-name>example</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>example</servlet-name>

<url-pattern>/example/*</url-pattern>

</servlet-mapping>

</web-app>

ApplicationContext的功能中,ApplicationContext实例。在Web MVC框架中,每个DispatcherServlet拥有自己的WebApplicationContext,它继承与所有的在根WebApplicationContext中定义的bean。根WebApplicationContext应该包含所有的组件bean,这些bean需要在当前的DispatcherServlet上下文和其他的上下文中共享。这些集成的bean可以在特定的Servlet范围中被重写,并且可以根据指定的Servlet实例重新定义bean。

Spring Web MVC中的上下文分层

基于DispatcherServlet的初始化。Spring MVC会寻找名称为[servlet-name]-servlet.xml的配置文件,并且基于此来创建定义的bean,并且重写所有在全局作用域的具有相同名字的bean。

下面的文件为DispatcherServlet的一种配置。

<web-app>

<servlet>

<servlet-name>golfing</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>golfing</servlet-name>

<url-patter>/golfing/*</url-pattern>

</servlet-mapping>

</web-app>


基于上面的配置,需要定义对应的bean配置文件,该文件的名称应当为/WEB-INF/golfing-servlet.xml,该文件会包含所有的Spring Web MVC的组件。当然可以通过修改Servlet的初始化参数来改变配置文件的位置。

当前对于单个的DispatcherServlet也可以仅仅只有一个根上下文。

可以通过设定contextConfigLocation初始化参数来改变配置文件位置。

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/root-context.xml</param-value>

</context-param>

<servlet>

<servlet-name>dispatcher</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value></param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>dispatcher</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listern-class>

</listener>

</web-app>

WebApplicationContext是ApplicationContext的扩展。它提供了处理主题的功能,并且它可以获取相关的Servlet引用。WebApplicationContext限制在ServletContext之中,并且通过在RequestContextUtils中使用静态方法可以方便的获取到WebApplicationContext。

同样我们可以通过基于java代码的配置实现。

public class GolfingWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

@override

protected class<?>[] getRootConfigClasses(){

return new Class[]{GolfingAppConfig.class};

}

@Override

protected Class<?>[] geteServletConfigClasses(){

return new Class[]{GolfingWebConfig.class};

}

@Override

protected String[] getServletMappings(){

return new String[]{”/golfing/*“};

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容