本文转载于http://www.open-open.com/lib/view/open1338338587698.html。请尊重版权,如有转载请说明。
现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,
框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。
一、Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0)
1. jar包引入
Spring 2.5.6:spring.jar、spring-webmvc.jar、commons-logging.jar、cglib-nodep-2.1_3.jar
Hibernate 3.6.8:hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、antlr-2.7.6.jar、
commons-collections-3.1、dom4j-1.6.1.jar、javassist-3.12.0.GA.jar、jta-1.1.jar、slf4j-api-1.6.1.jar、slf4j-nop-1.6.4.jar、相应数据库的驱动jar包
2. web.xml配置(部分)
01 |
<!-- Spring MVC配置 --> |
02 |
<!-- ====================================== --> |
03 |
< servlet > |
04 |
< servlet-name >spring</ servlet-name > |
05 |
< servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class > |
06 |
<!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下, |
07 |
<init-param> |
08 |
<param-name>contextConfigLocation</param-name> |
09 |
<param-value>/WEB-INF/spring-servlet.xml</param-value> 默认 |
10 |
</init-param> |
11 |
--> |
12 |
< load-on-startup >1</ load-on-startup > |
13 |
</ servlet > |
14 |
|
15 |
< servlet-mapping > |
16 |
< servlet-name >spring</ servlet-name > |
17 |
< url-pattern >*.do</ url-pattern > |
18 |
</ servlet-mapping > |
19 |
|
20 |
|
21 |
|
22 |
<!-- Spring配置 --> |
23 |
<!-- ====================================== --> |
24 |
< listener > |
25 |
< listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > |
26 |
</ listener > |
27 |
|
28 |
|
29 |
<!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 --> |
30 |
< context-param > |
31 |
< param-name >contextConfigLocation</ param-name > |
32 |
< param-value >classpath:config/applicationContext.xml</ param-value > |
33 |
</ context-param > |
3. spring-servlet.xml配置
spring-servlet这个名字是因为上面web.xml中<servlet-name>标签配的值为spring(<servlet-name>spring</servlet-name>),
再加上“-servlet”后缀而形成的spring-servlet.xml文件名,如果改为springMVC,对应的文件名则为springMVC-servlet.xml。
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
< beans xmlns = "http://www.springframework.org/schema/beans" |
03 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:p = "http://www.springframework.org/schema/p" |
04 |
xmlns:context = "http://www.springframework.org/schema/context" |
05 |
xsi:schemaLocation="http://www.springframework.org/schema/beans |
06 |
http://www.springframework.org/schema/aop |
07 |
http://www.springframework.org/schema/tx |
08 |
http://www.springframework.org/schema/context href = "http://www.springframework.org/schema/context/spring-context-3.0.xsd" > a >"> |
09 |
|
10 |
<!-- 启用spring mvc 注解 --> |
11 |
< context:annotation-config /> |
12 |
|
13 |
<!-- 设置使用注解的类所在的jar包 --> |
14 |
< context:component-scan base-package = "controller" ></ context:component-scan > |
15 |
|
16 |
<!-- 完成请求和注解POJO的映射 --> |
17 |
< bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> |
18 |
|
19 |
<!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 --> |
20 |
< bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix = "/jsp/" p:suffix = ".jsp" /> |
21 |
</ beans > |
4. applicationContext.xml配置
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
< beans xmlns = "http://www.springframework.org/schema/beans" |
03 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" |
04 |
xmlns:aop = "http://www.springframework.org/schema/aop" |
05 |
xmlns:tx = "http://www.springframework.org/schema/tx" |
06 |
xsi:schemaLocation=" |
07 |
http://www.springframework.org/schema/beans |
08 |
http://www.springframework.org/schema/aop |
09 |
http://www.springframework.org/schema/tx |
10 |
|
11 |
<!-- 采用hibernate.cfg.xml方式配置数据源 --> |
12 |
< bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" > |
13 |
< property name = "configLocation" > |
14 |
< value >classpath:config/hibernate.cfg.xml</ value > |
15 |
</ property > |
16 |
</ bean > |
17 |
|
18 |
<!-- 将事务与Hibernate关联 --> |
19 |
< bean id = "transactionManager" class = "org.springframework. > |
20 |
< property name = "sessionFactory" > |
21 |
< ref local = "sessionFactory" /> |
22 |
</ property > |
23 |
</ bean > |
24 |
|
25 |
<!-- 事务(注解 )--> |
26 |
< tx:annotation-driven transaction-manager = "transactionManager" proxy-target-class = "true" /> |
27 |
|
28 |
<!-- 测试Service --> |
29 |
< bean id = "loginService" class = "service.LoginService" ></ bean > |
30 |
|
31 |
<!-- 测试Dao --> |
32 |
< bean id = "hibernateDao" class = "dao.HibernateDao" > |
33 |
< property name = "sessionFactory" ref = "sessionFactory" ></ property > |
34 |
</ bean > |
35 |
</ beans > |
二、详解
Spring MVC与Struts从原理上很相似(都是基于MVC架构),都有一个控制页面请求的Servlet,处理完后跳转页面。看如下代码(注解):
01 |
package controller; |
02 |
|
03 |
import javax.servlet.http.HttpServletRequest; |
04 |
|
05 |
import org.springframework.stereotype.Controller; |
06 |
import org.springframework.web.bind.annotation.RequestMapping; |
07 |
import org.springframework.web.bind.annotation.RequestParam; |
08 |
|
09 |
import entity.User; |
10 |
|
11 |
@Controller //类似Struts的Action |
12 |
public class TestController { |
13 |
|
14 |
@RequestMapping ( "test/login.do" ) // 请求url地址映射,类似Struts的action-mapping |
15 |
public String testLogin( @RequestParam (value= "username" )String username, String password, |
16 |
// @RequestParam是指请求url地址映射中必须含有的参数(除非属性required=false) |
17 |
// @RequestParam可简写为:@RequestParam("username") |
18 |
|
19 |
if (! "admin" .equals(username) || ! "admin" .equals(password)) { |
20 |
return "loginError" ; // 跳转页面路径(默认为转发), |
21 |
} |
22 |
return "loginSuccess" ; |
23 |
} |
24 |
|
25 |
@RequestMapping ( "/test/login2.do" ) |
26 |
public ModelAndView testLogin2(String username, String password, int age){ |
27 |
// request和response不必非要出现在方法中,如果用不上的话可以去掉 |
28 |
// 参数的名称是与页面控件的name相匹配,参数类型会自动被转换 |
29 |
|
30 |
if (! "admin" .equals(username) || ! "admin" .equals(password) || age < 5 ) { |
31 |
return new ModelAndView( "loginError" ); // 手动实例化ModelAndView完成跳转页面(转发), |
32 |
} |
33 |
return new ModelAndView( new RedirectView( "../index.jsp" )); // 采用重定向方式跳转页面 |
34 |
// 重定向还有一种简单写法 |
35 |
// return new ModelAndView("redirect:../index.jsp"); |
36 |
} |
37 |
|
38 |
@RequestMapping ( "/test/login3.do" ) |
39 |
public ModelAndView testLogin3(User user) { |
40 |
// 同样支持参数为表单对象,类似于Struts的ActionForm,User不需要任何配置,直接写即可 |
41 |
String username = user.getUsername(); |
42 |
String password = user.getPassword(); |
43 |
int age = user.getAge(); |
44 |
|
45 |
if (! "admin" .equals(username) || ! "admin" .equals(password) || age < 5 ) { |
46 |
return new ModelAndView( "loginError" ); |
47 |
} |
48 |
return new ModelAndView( "loginSuccess" ); |
49 |
} |
50 |
|
51 |
@Resource (name = "loginService" ) // 获取applicationContext.xml中bean的id为loginService的,并注入 |
52 |
private LoginService loginService; //等价于spring传统注入方式写get和set方法, |
53 |
|
54 |
@RequestMapping ( "/test/login4.do" ) |
55 |
public String testLogin4(User user) { |
56 |
if (loginService.login(user) == false ) { |
57 |
return "loginError" ; |
58 |
} |
59 |
return "loginSuccess" ; |
60 |
} |
61 |
} |
以上4个方法示例,是一个Controller里含有不同的请求url,也可以采用一个url访问,通过url参数来区分访问不同的方法,代码如下:
01 |
package controller; |
02 |
|
03 |
import org.springframework.stereotype.Controller; |
04 |
import org.springframework.web.bind.annotation.RequestMapping; |
05 |
import org.springframework.web.bind.annotation.RequestMethod; |
06 |
|
07 |
@Controller |
08 |
@RequestMapping ( "/test2/login.do" ) // 指定唯一一个*.do请求关联到该Controller |
09 |
public class TestController2 { |
10 |
|
11 |
@RequestMapping |
12 |
public String testLogin(String username, String password, int age) { |
13 |
// 如果不加任何参数,则在请求/test2/login.do时,便默认执行该方法 |
14 |
|
15 |
if (! "admin" .equals(username) || ! "admin" .equals(password) || age < 5 ) { |
16 |
return "loginError" ; |
17 |
} |
18 |
return "loginSuccess" ; |
19 |
} |
20 |
|
21 |
@RequestMapping (params = "method=1" , method=RequestMethod.POST) |
22 |
public String testLogin2(String username, String password) { |
23 |
// 依据params的参数method的值来区分不同的调用方法 |
24 |
// 可以指定页面请求方式的类型,默认为get请求 |
25 |
|
26 |
if (! "admin" .equals(username) || ! "admin" .equals(password)) { |
27 |
return "loginError" ; |
28 |
} |
29 |
return "loginSuccess" ; |
30 |
} |
31 |
|
32 |
@RequestMapping (params = "method=2" ) |
33 |
public String testLogin3(String username, String password, int age) { |
34 |
if (! "admin" .equals(username) || ! "admin" .equals(password) || age < 5 ) { |
35 |
return "loginError" ; |
36 |
} |
37 |