(一)什么是Spring MVC
Spring MVC是spring的一个子框架,或者说一个模块,是目前市面上最流行的Web控制器框架,其市场占有率已超过JSF,Struts1,Struts2等过去处于霸主地位的Web框架。Spring MVC功能强大,简单易学,有其他Web框架使用经验(比如struts2)的开发人员可以很快上手Spring MVC。
(二)为什么要学Spring MVC
因为spring框架有几个优点:
1. 属于spring生态系统的一部分,只是最重要的优势。一方面spring mvc以充分利用spring的种种优势,比如注解配置、IOC、AOP、COC思想等等,另一方面与spring其他子框架的结合就更为自然,而且可。同时由于spring在JavaEE轻量级框架中的霸主地位,拥有众多活跃社区,Spring MVC会随着spring一同快速发展,这是其他框架所不具有的优势,。像最新的spring boot技术可以很好地与spring MVC集成,让你第一次感觉到,构建一个Web应用比构建一个桌面应用更简单快捷。
2. 支持多视图无缝切换。基于适配器模式设计的视图解析器可以让应用同时支持多种视图的响应。不管你想输出JSP,HTML还是JSON,甚至是PDF,同样的程序,同样的数据,只需改动微量配置,就可以做到自动切换,这才叫真正的数据与视图分离,这才叫MVC。在当今客户端类型众多的时代,这样的特性当然非常有用。
3. 相比红极一时的Struts2,对对象scope的管理更加灵活。众所周知,由于struts2的设计是用控制器类(Action)的属性来映射请求参数,所以其Action对象的产生方式只能是原型,否则会有线程安全问题。在当今并发量与日俱增的时代,这样反复创建无意义对象的方式会对性能造成很大的负担。而spring mvc的控制器类(controller)依然作为spring bean,受到spring容器对对象的管理,可以灵活选择用singleton还是prototype的方式产生(当然,默认是singleton),同时spring mvc采用方法参数的形式来接收客户端参数,也避免了线程安全问题。
4. 最现实的优点是:基于以上优点(当然,Spring MVC博大精深,以上只列出了部分对开发人员最显而易见的优点),spring mvc应用广泛,熟练使用spring mvc意味着你选择工作的机会更多,薪水也可能更高。
(三)第一个Spring MVC例子–Hello Spring MVC
说了那么多废话,还是做个Hello World的例子看看Spring MVC完成一个简单的HTTP请求响应跟其他框架有什么不一样,这是学任何技术的入门之道。
注意:本教程使用eclipse作为IDE,使用其他IDE大同小异,具体操作请参考相关资料
1. 导jar包。任何框架的配置,第一件事永远都是先找齐框架所依赖的jar文件。在Maven已经大行其道的今天,再去手工地一个一个找jar,在似乎无穷尽的ClassNotFount中煎熬未免太落伍了,所以这个例子我们直接采用Maven的方式配置spring mvc的依赖环境。
1)在eclipse中选择new->other,在过滤窗口中输入maven,选择maven project, 然后next->next
2) 在maven项目模板中选择maven-archtype-webapp,next创建一个maven web工程
3)填写相应的maven坐标,version会自动生成,主要填写groupid(我们这里设为com.training.spring)和artifactid(这里设为HelloSpringMVC)即可(关于maven的基本知识就不在这里赘述了),完成以后eclipse会为我们生成基本的项目结构(JDK版本1.8)
4)编写POM文件,配置相关依赖
首先,junit的依赖,虽然maven插件一般能自动生成,但是版本可能较低,最好改成4.x版的,以后可以充分利用spring的单元测试框架
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1</version>
</dependency>
接着是servlet的依赖,任何Java平台下的web框架,核心的控制器还是servlet,这里配成3.0版本
<!– https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api –>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
最后配spring mvc所需jar,只需加这么一个dependency,就可以自动从maven仓库下载spring mvc相关jar,同时会把相关Jar所依赖的jar以及所依赖Jar所依赖Jar一块下下来,完全不用开发人员自己去找,方便吧。这些依赖所对应maven坐标也不需要你记,需要什么直接从这个网站去找即可http://mvnrepository.com/
<!– https://mvnrepository.com/artifact/org.springframework/spring-webmvc –>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
当然,通常还需要配置些maven执行任务所需的基本属性和插件,如jdk版本,编码字符集等,完整的pom.xml文件我上传在附件中。
5)同步maven配置。编写好pom以后,右击项目,选择maven->update project,将pom的配置信息同步到eclipse中,以后我们每次改了pom文件,最好都这样同步一下。同步完成后观察我们的工程,会多出一个maven的库,刚才在pom文件中声明的依赖jar都在这个库下,并且自动导入了build path。如果你打开pom文件的dependency hierarchy选项卡,还可以看到他们相互依赖的层次关系。这就是使用eclipse maven插件所带来的便利。
(6)在web.xml中配置spring mvc的启动环境
依赖环境配好以后就可以写配置文件了。 跟struts等其他MVC框架类似,spring mvc容器的启动也是依赖于web应用的容器先启动,所以我们在当前应用的web.xml文件中配置其核心控制器DispatcherServlet。可以从名字看出spring mvc是依靠一个servlet加载环境的,这是和struts2有区别的。
<!–配置spring mvc核心控制器 –>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern><!–表示拦截所有请求–>
</servlet-mapping>
其中的初始化参数contextConfigLocation指向一个自定义的spring mvc配置文件,类似于struts2的struts.xml,名字可以自己取,路径我们定义在当前应用的classpath下。注意:JavaEE6以后的版本(也就是servlet3以后的版本)支持用编程的方式启动Web容器,这里我们照顾大多数项目的习惯,还是沿用传统配置文件的方式。后面我们会有一节专门讲述用编程的方式即零配置地实现spring mvc容器的启动。
(7)在spring mvc配置文件中配置第一个controller
在src/main/resources目录下添加一个叫做springmvc-config.xml 的xml文件,文件名要与web.xml中声明的spring mvc配置文件名一致,在文件中配置两个节点即可。
第一个是component-scan,用于指定要spring容器自动扫描的基础包。因为spring mvc通常采用注解配置,所以需要指定哪些包下的类需要自动扫描,这样可以减少绝大多数bean在配置文件中的声明
<!– scan the package and the sub package –>
<context:component-scan base-package=”com.training.spring”/>
第二,在配置文件中声明spring mvc唯一必须声明的一个bean,那就是视图解析器,这里我们使用最常用的InternalResourceViewResolver。注意这里的两个子节点,prefix表示视图URL的前缀,suffix表示视图URL的后缀,中间的部分由controller类来返回,这个我们后面再说。
<!– configure the InternalResourceViewResolver –>
<bean class=”org.springframework.web.servlet.view.InternalResourceViewResolver”
id=”internalResourceViewResolver”>
<!– 前缀 –>
<property name=”prefix” value=”/WEB-INF/jsp/” />
<!– 后缀 –>
<property name=”suffix” value=”.jsp” />
</bean>
(8)编写controller类
到此为止,所有配置都完成了,终于可以写程序了。在src/main/java中自己建个包,然后写一个POJO,这里我们叫HelloSpringMVC.java,加上相应注解(见图片),写一个sayHello方法,返回String类型。如下所示:
这里就简单打印一句话表示类执行了,结束时返回一个叫“index”的字符串(叫什么名字无所谓),这个字符串可以视作视图URL中间部分,跟之前配置文件中定义的视图解析器的前缀和后缀拼装在一起,就构成了完整的视图URL。以这个例子来说,我们定义的视图路径前缀是/WEB-INF/jsp/,后缀是.jsp,控制器类返回的是index,就表示视图的URL应该是 当前应用上下文/WEB-INF/jsp/index.jsp。所以你要测试的话需要在相应路径下建立相应文件,在文件里随便写点什么能显示出来即可。
可以看得出,spring mvc的controller同struts2的action类似,都是一个POJO即可,不需要绑定任何框架相关API。这里我们加了一个spring的注解@controller在类上,配合自动扫描,就把这个POJO变成了springmvc的控制器组件,并作为一个bean纳入spring容器管理,将来要利用spring的其他特性,如IOC,AOP等也是非常容易,比struts2与spring的整合更加方便,因为spring mvc本来就是spring框架的一部分,可以说是天然集成。至于另一个注释requestmapping,相信有经验的人马上就能猜出来是配置客户端访问该控制器路径的,该注释可以用在类和方法两个级别上,以后我们在详细讲解。(注意:控制器的访问路径和视图名没有任何关系,只是例子中写成一样了)
(9)打包运行
右击eclipse中的工程,选择run as,先后执行maven clean和maven install,maven插件会自动将项目打成一个war包,放在target目录下,将WAR文件拷到你的TOMCAT_HOME/webapps下,启动tomcat即可加载该web应用。
启动成功后,在浏览器中输入http://ip:tomcat端口号/web应用名称/index
不用加任何后缀,即可执行该控制器逻辑,并返回响应视图组件。
(四)总结
本文简要介绍目前最流行的,也是spring官方所推荐web控制器框架(自己的产品当然推荐了)–spring mvc的主要特点,并结合Maven详细讲解了一个最简单的spring mvc例子。可以看出,spring mvc充分利用了spring的注解机制,大大减少了配置文件编写的工作量(整个配置量不超过30行),语义清晰,并且简单易学。当然,spring mvc博大精深,在快速完成我们第一个Hello Spring的程序后,有了一点感性认识,我们后面就如庖丁解牛一般,以实际应用场景为向导,一点一点地讲解spring mvc的各种强大的功能。注:相关配置文件作为附件上传,请大家自行下载