spring-mvc入门(一):入门实例 及后端控制器

1.MVC :Model-View-Control
框架性质的C 层要完成的主要工作:封装web 请求为一个数据对象、调用业务逻辑层来处理数据对象、返回处理数据结果及相应的视图给用户。
2. 简要概述springmvc
Spring C 层框架的核心是 DispatcherServlet,它的作用是将请求分发给不同的后端处理器,也即 使用了一种被称为Front Controller 的模式(后面对此模式有简要说明)。 Spring 的C 层框架使用了后端控制器来、映射处理器和视图解析器来共同完成C 层框架的主要工作。并且spring 的C 层框架还真正地把
业务层处理的数据结果和相应的视图拼成一个对象,即我们后面会经常用到的ModelAndView 对象。

一、入门实例
1. 搭建环境
在spring 的官方API 文档中,给出所有包的作用概述,现列举常用的包及相关作用:
org.springframework.aop-3.0.5.RELEASE.jar :与Aop 编程相关的包
org.springframework.beans-3.0.5.RELEASE.jar :提供了简捷操作bean 的接口
org.springframework.context-3.0.5.RELEASE.jar :构建在beans 包基础上,用来处理资源文件及国际化。
org.springframework.core-3.0.5.RELEASE.jar :spring 核心包
org.springframework.web-3.0.5.RELEASE.jar :web 核心包,提供了web 层接口
org.springframework.web.servlet-3.0.5.RELEASE.jar :web 层的一个具体实现包,DispatcherServlet也位于此包中。
后文全部在spring3.0 版本中进行,为了方便,建议在搭建环境中导入spring3.0 的所有jar 包(所有jar 包位于dist 目录下)。

2. 编写HelloWorld 实
步骤一、建立名为springMVC_01_helloword ,并导入上面列出的jar 包。
步骤二、编写web.xml 配置文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>spmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

简要说明 :DispatcherServlet 就是一个Servlet ,也是对请求进行转发的核心Servlet 。在这里即所有.do 的请求将首先被DispatcherServlet 处理,而ispatcherServlet 它要作的工作就是对请求进行分发(也即是说把请求转发给具体的Controller )。可以简单地认为,它就是一个总控处理器,但事实上
它除了具备总控处理理器对请求进行分发的能力外,还与spring 的IOC 容器完全集成在一起,从而可以更好地使用spring 的其它功能。在这里还需留意 < servlet-name > spmvc </ servlet-name > ,下面步骤三会用到。
步骤三、建立 spmvc-servlet.xml 文件,它的命名规则: servlet-name-servlet.xml 。它的主要代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean id="simpleUrlHandlerMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/hello.do">helloControl</prop>
			</props>
		</property>
	</bean>
	<bean id="helloControl" class="com.asm.HelloWord"></bean>
</beans>

说明: hello.do 的请求将给名为 helloControl 的 bean 进行处理。
步骤四、完成 HelloWord.java 的编写,代码如下:

package com.icbc.springmvc.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloWorld implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView("hello.jsp");
		mav.addObject("message", "Hello World!");
		
		return mav;
	}

}

说明 :ModelAndView 对象是包含视图和业务数据的混合对象,即是说通过此对象,,我们可以知道所返回的相应页面(比如这里返回hello.jsp 页面),也可以在相应的页面中获取此对象所包含的业务数据(比如这里message-hello worrld )。

步骤五、在当前项目web 根目录下编写hello.jsp ,主要代码如下:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
世界,你好!
获取值: ${message }
</body>
</html>

4. 简析spring mvc 工作原理

(1 )启动服务器,根据web.xml 的配置加载前端控制器(也称总控制器) DispatcherServlet 。在加载时、会完成一系列的初始化动作。
(2 )根据servlet 的映射请求(上面的helloWorld 实例中针对.do 请求),并参照“控制器配置文件”(即spmvc-servlet.xml 这样的配置)文件,把把具体的请求分发给特定的后端控制器进行处理(比如上例会分发给HelloWorld 控制器进行处理)
(3 )后端控制器调用相应的逻辑层代码,完成处理并返回视图对象( ModelAndView )给前端处理器。
(4 )前端控制器根据后端控制器返回的 ModelAndView 对象,并结合一些配置(后面有说明),返回一个相应的页面给客户端。
小结 :这种Front Controller 模式常应用在主流的web 框架中,比如典型的struts1.x 框架.Front
Controller 模式:所有请求先交给一个前端处理器(总控处理器)处理,然后前端处理器会参照一些配置文件再把具体的请求交给相应的后端处理器。后端处理器调用逻辑层代码,并根据逻辑返回相应的视图对象给前端控制器。然后前端控制器再根据视图对象返回具体的页面给客户端(提示:和spring mvc一样,在struts1.x 中前端控制器是Servlet, 而在struts2 中前端控制器是Filter )。

5. 初识spring mvc 的视图
在前面的HelloWorld 实例中,在HelloWorld.java 中返回 ModelAndView mav = new ModelAndView(“hello.jsp” ) 参数为 hello.jsp ,它会对应于当前项目根目录下的 hello.jsp 页面。但 spring mvc 为我们提供了一个特别的视图定位方式,下面改进前面的 HelloWord 实例:
改进一 :在 spmvc-servlet.xml 中增加如下代码:

<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>

改进二 :在HelloWorld.java 重新定义返回的 ModelAndView 对象,即把 ModelAndView mav = new ModelAndView( “hello.jsp” ) 改为 ModelAndView mav = new ModelAndView( “hello” )
改进三 :在/WEB-INF/page 目录下建立hello.jsp 页面
进行上面三个改进操作后,重新访问hello.do 会访问到WEB-INF/page/hello.jsp 页面。
简析视图定位:当返回 ModelAndView 对象名称为hello 时,会给hello 加上前后缀变成/WEB-INF/page/hello.jsp 。。因此在给前后缀赋值时,应特别注意它和返回的 ModelAndView 对象能否组成一个正确的文件全路径。在前面的“简析spring mvc 工作原理(4) ”点中提到在根据ModelAndView 对象返回页面时,会结合一些配置。这里就是结合了视图定位方式,给viewName加上前后缀进行定位。

1.2 spring-mvc入门(二):后端控制器(上)
1.概述SpringMVC后端控制器
为了方便开发人员快捷地建立适合特定应用的后端控制器,springMVC实现Controller接口,自定义了许多特定控制器。这些控制器的层次关系如下:
在这里插入图片描述
下面重点分析两个特色控制器:
2.SimpleFormController控制器
在正式开发前,请先熟悉上前面的HelloWord实例。在保证熟悉前一个实例后,我们建立名
为springMVC_02_controllerweb项目,并导入相关的jar包。
步骤一:建立后端控制器RegControl.java代码如下:

package com.icbc.springmvc.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.icbc.springmvc.domain.User;

public class RegControl extends SimpleFormController {
	@SuppressWarnings("deprecation")
	public RegControl() {
		setCommandClass(User.class);
	}

	protected ModelAndView processFormSubmission(HttpServletRequest arg0, HttpServletResponse arg1, Object formbean,
			BindException arg3) throws Exception {

		User user = (User) formbean;
		ModelAndView mav = new ModelAndView("hello");
		mav.addObject("message", "Hello World!");
		mav.addObject("user", user);
		return mav;
	}

	protected ModelAndView showForm(HttpServletRequest arg0, HttpServletResponse arg1, BindException arg2)
			throws Exception {
		return null;
	}
}

User.java,代码如下:

package com.icbc.springmvc.domain;

public class User {
	private String username;
	private int age;
	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}
	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}
	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}
	/**
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}
	public User(String username, int age) {
		super();
		this.username = username;
		this.age = age;
	}
	
	public User() {
		// TODO Auto-generated constructor stub
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "User [username=" + username + ", age=" + age + "]";
	}
}

简要说明:如果熟悉struts1.x相信很容易理解Object formbean参数,其实它就是和表单属性打交道的一个对象,也即是说表单参数会依据一定的规则填充给formbean对象。在struts1.x中,如果像把这种与formbean转换成User对象,必须要求User继承自ActionForm类,这样才能把一个表单参数转换成一个具体的formbean对象(所谓具体实质是指参数formbean对象已经能成功地赋值给User对象)并与相应的Action绑定。但springmvc并不要求这种User一定要继承某个类,既然springmvc对这种User没有要求,那表单参数是怎样与User进行完美匹配的,注意在RegControl构造方法中有如下一句代码:setCommandClass(User.class);这句代码就指明了此控制器绑定User类来和表单进行匹配。如果想验证此句代码的作用,可以注释掉这句代码并查看
异常。后面将会分析这种控制器的一个执行过程(包括表单填充及验证过程)

概述此步要点:(1)继承SimpleFormController类
(2)构造器中调用setCommandClass方法绑定定命令对象(这里为User类)
(3)转换formbean为User类进行业务逻辑操作
步骤二:配置web.xml(和前面HelloWorld实例一样,在此省略)
步骤三:配置spmvc-servlet.xml文件,代码如下:

<beans>
	<bean id="simpleUrlHandlerMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/reg.do">regControl</prop>
			</props>
		</property>
	</bean>
	<bean id="regControl" class="com.icbc.springmvc.controller.RegControl"></bean>
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

步骤四:根据配置文件完善相应页面
在index.jsp设定表单填写页面,主要代码如下:

<form action="<%=request.getContextPath()%>/reg.do" method="post">
用户名:<input type="text" name="username"><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit">
</form>

/page/hello.jsp,主要代码如下:

世界,你好!(WEB-INF/page)
用户名:${user.username }
年龄:${user.age }

步骤五:启动服务器,访问到首页,填写表单完成测试。

3.细研SimpleController控制器

在RegControl.java中增加如下代码:

protected Object formBackingObject(HttpServletRequest request) throws Exception {
System.out.println("formBackingObject方法执行-->01");
setCommandClass(User.class); //也可在此处调用setCommandClass方法
return super.formBackingObject(request);
}
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
System.out.println("initBinder方法执行-->02");
super.initBinder(request, binder);
}
protected void onBind(HttpServletRequest request, Object command) throws Exception {
System.out.println("onBind方法执行-->03");
super.onBind(request, command);
}
protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors)
throws Exception {
System.out.println("onBindAndValidate方法执行-->04");
super.onBindAndValidate(request, command, errors);
}

下面简要分析执行过程:
(1).当前端控制器把请求转交给此此控制器后,会首先调用formBackingObject方法此方法的作用就是根据绑定的Command Class来创建一个Command对象,因此除了可以在构造方法中调用setCommandClass方法,也可以在此处调用setCommandClass方法。其实创建这个Command对象很简单,spring通过如下代码完成:
BeanUtils.instantiateClass(this.commandClass);由于在此处必须根据commandClass来完成Command对象的创建,因此在此方法调用前应保证commandClass设置完成,所以我们可以在formBackingObject方法和构造方法中完成commandClass的设置。
(2).调用initBinder方法,初始化Command对象,即把表单参数与Command字段按名称进行匹配赋值。
(3).调用onBind方法,把Command对象和后端控制器绑定。
(4).调用onBindAndValidate方法,验证用户输入的数据是否合法。如果验证失败,我们可以通过修改errors参数,即新的errors对象将会绑定到ModelAndView上并重新回到表单填写页面。
(5).执行processFormSubmission方法,主要操作就是把绑定的Command对象转换成一个User这样的表单对象,并调用业务逻辑方法操作User对象,根据不同的逻辑返回不同的ModelAndView对象。

4.MultiActionController控制器
此控制器来将多个请求处理方法合并在一个控制器里,这样可以把相关功能组合在一起(它和struts1.x中的DispatchAction极为相似)。下面通过实例演示此控制器的使用。

步骤一:在springMVC_02_controllerweb项目下,建立后端控制器UserManagerController.java,代码如下:

public class UserManagerController extends MultiActionController {
	public ModelAndView list(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("list");
		return mav;
		}
		public ModelAndView add(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("add");
		return mav;
		}
		public ModelAndView edit(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("edit");
		return mav;
		}
}

步骤二:配置web.xml(参前面实例),并在spmvc-servlet.xml中增加如下配置:

<bean id="springMethodNameResolver"
		class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
		<property name="mappings">
			<props>
				<prop key="/list.do">list</prop>
				<prop key="/add.do">add</prop>
				<prop key="/edit.do">edit</prop>
			</props>
		</property>
	</bean>

	<bean id="userManagerController" class="com.icbc.springmvc.controller.UserManagerController">
		<property name="methodNameResolver" ref="springMethodNameResolver">
		</property>
	</bean>

说明:
methodNameResolver负责从请求中解析出需要调用的方法名称。Spring本身已经提供了一系列MethodNameResolver的实现,当然也可以编写自己的实现。在这里我们使用了Pro方式来解析,具体表现如下:
list 请求list.do时调用list方法
add 请求为add.do时调用add方法
edit 请求为edit.do时调用edit方法
然后通过把springMethodNameResolver解析器注入给UserManagerController的methodNameResolver,这样配置后才完成了一个真正的具有请求转发能力的MultiActionController控制器对象——UserManagerController 强调:此步骤实质
完成了一个工作:就是为UserManagerController控制器配置一个方法解析器。

步骤三:配置请求转发的访问路径,在spmvc-servlet.xml中添加如下代码

<bean id="simpleUrlHandlerMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/list.do">userManagerController</prop>
				<prop key="/add.do">userManagerController</prop>
				<prop key="/edit.do">userManagerController</prop>
			</props>
		</property>
	</bean>

步骤四:根据配置文件,完善jsp页面编写。
page/list.jsp,代码如下:

用户列表页面 page/add.jsp,代码如下: 用户添加页面 page/edi.jsp,代码如下: 用户修改页面

步骤五:
启动服务器,访问…/list.do将调用到list方法并转向到list.jsp页面。
补充:细说MethodNameResolver解析器
InternalPathMethodNameResolver 默认MethodNameResolver解析器,从请求路径中获取文件名作为方法名。比如,…/list.do的请求会调用list(HttpServletRequest,HttpServletResponse)方法。ParameterMethodNameResolver:解析请求参数,并将它作为方法名。比如,对应…/userManager.do?method=add的请求,会调用 add(HttpServletRequest, HttpServletResponse)方法。使用paramName属性定义要使用的请求参数名称。
PropertiesMethodNameResolver :使用用户自定义的属性(Properties)对象,将请求的URL映射到方法名,具体可以参见实例。
使用ParameterMethodNameResolver作为MethodNameResolver的解析器时,主要配置代码如下:

<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/user.do">userManagerController</prop>
</props>
</property>
</bean>
<bean id="ParameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="crud"></property>
</bean>
<bean id="userManagerController"

class="com.asm.UserManagerController">
<property name="methodNameResolver"
ref="ParameterMethodNameResolver">
</property>
</bean>

访问路径为…/user.do?crud=list(add|edit)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值