FilterDispatcher是Struts 2框架的核心控制器
DispatcherServlet是Spring框架的核心控制器
23.2 Spring MVC的控制器
和Struts2一样,Spring MVC框架的控制器也用来建立视图层和模型层的联系,Spring的控制器可以通过继承一些接口来实现,下面进行讲解。
23.2.1 核心控制器DispatcherServlet
DispatcherServlet是Spring MVC的核心控制器,其作用相当于Struts2的FilterDispatcher,负责对客户端的请求进行分发,把满足特定格式的请求交给业务控制器去处理。
1.DispatcherServlet的配置
【示例23-4】下面通过一段代码来说明在web.xml中如何配置DispatcherServlet。
<context-param> <!--配置contextConfigLocation 参数-->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-jdbc.xml</param-value>
</context-param>
<servlet> <!--配置DispatcherServlet -->
<servlet-name>petclinic</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping> <!--为DispatcherServlet 建立映射-->
<servlet-name>petclinic</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
上面的代码通过contextConfigLocation参数来定义Spring MVC的配置文件,这样当DispatcherServlet初始化时就会加载该文件中的配置信息。把DispatcherServlet的URL映射为*.htm,这样所有的以.htm结尾的请求都会被DispatcherServlet处理。
2.DispatcherServlet的工作流程
当DispatcherServlet接收到用户请求后,按照如下步骤进行处理。
(1)搜索封装配置文件信息的WebApplicationContext,并将它作为一个属性存储在请求对象中,这样DispatcherServlet就可以使用WebApplicationContext调用配置文件中定义的源。
(2)把本地化信息、主体信息也存储到请求对象上。
(3)根据配置文件搜索合适的业务处理器,并准备用于返回的ModelAndView。
(4)当业务处理器处理完业务逻辑后,根据WebApplicationContext中绑定的视图信息显示对应的视图。
23.2.2 控制器接口Controller
Controller接口是所有控制器接口的父类,所有Spring框架提供的控制器,以及所有用户自定义的控制器都得实现这个接口。
【示例23-5】该示例分析Controller.Java的源代码,如下所示。
package org.springframework.web.servlet.mvc;
import Javax.servlet.http.HttpServletRequest;
import Javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
public interface Controller {
ModelAndView handleRequest(HttpServletRequest
request, HttpServletResponse
response) throws Exception;
}
可以看出,该接口的handleRequest(HttpServletRequest request, HttpServletResponse response)方法用来对用户的请求进行处理,所有的实现类都要重写这个方法,该方法对请求处理完后返回一个ModelAndView对象。
23.2.3 表单控制器SimpleFormController
SimpleFormController可以自动将用户从表单获取的参数存入一个JavaBean的实例中,这样就不用逐一调用request.getAttribute()方法去获取,下面通过一个例子来讲解。
【示例23-6】该示例按照编程步骤创建表单控制器。首先,创建用于用户提交表单的页面simplelogin.jsp,代码如下:
<%@page contentType="text/html;charset=UTF-8"%>
<html>
<head><title>登录</title></head>
<body>
请输入登录信息:<form action="simplelogin.do" method="post">
<br>用户名:<input type=text name=userName>
<br>密码:<input type=password name=password>
<br><input type=submit name=submit>
</form>
</body>
</html>
可以看出该页面把请求提交给simplelogin.do去处理。下面看LoginBean.java的代码,如下所示。
package com.examp.ch23;
public class LoginBean {
private String userName; //该属性用于获取表单中的userName参数
private String password; //用于获取表单中的password参数
public String getUserName(){
return userName;
}
publicvoid setUserName(String userName){
this.userName = userName;
}
public String getPassword(){
returnthis.password;
}
publicvoid setPassword(String password){
this.password = password;
}
}
可以看出,该文件有两个属性userName和password,并且每个属性都有getter和setter方法。使用SimpleFormController、Spring MVC框架可以自动将表单的参数与该类的属性进行名字匹配,然后把参数值赋给属性。这样在控制器中就可以调用LoginBean的实例去获取表单参数。下面是SimpleLoginController.java,它实现了SimpleFormController接口,代码如下:
package com.examp.ch23;
import Java.util.HashMap;
import Java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
publicclass LoginController extends SimpleFormController{
//继承SimpleFormController类
private Logger logger = Logger.getLogger(this.getClass().getName());
private String viewPage;
protected ModelAndView onSubmit(Object command)
//在onSummit()方法中处理用户请求
throws Exception {
LoginBean loginbean = (LoginBean)command;
Map model = new HashMap();
model.put("userName", loginbean.getUserName());
//将loginbean中的userName存入model
ModelAndView mv = new ModelAndView(getViewPage(),model);
return mv;
}
publicvoid setViewPage(String viewPage){ //
调用该方法给属性viewPage赋值
this.viewPage = viewPage;
}
public String getViewPage(){ //调用该方法获取viewPage属性
returnthis.viewPage;
}
}
可以看出在该类的onSummit()方法中对simplelogin.jsp的请求进行处理。首先通过LoginBean的实例userbean获取表单参数,把它存入model,然后调用getViewPage获取配置文件中定义的返回页面去显示。下面看配置文件,代码如下:
<bean id="urlMapping"class="org.springframework.web.servlet.handler.Simp-
leUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="helloWorld.do">helloWorldAction</prop>
<!--为simpleLoginController 创建映射-->
<prop key="simplelogin.do">simpleLoginController</prop>
</props>
</property>
</bean>
<bean id="simpleLoginController"class="com.examp.
ch23.SimpleLoginController">
<property name="viewPage">
<value>simpleWelcomeView</value>
<!--viewPage属性用于指定返回的视图-->
</property>
<!--commandClass属性用于指定存储表单参数的JavaBean类-->
<property name="commandClass">
<value>com.examp.ch23.LoginBean</value>
</property>
</bean>
可以看出,上面代码在配置文件中给LoginController建立映射simplelogin.do,并给SimpleLoginController的属性赋值。viewPage的值为simpleWelcomeView,它对应于simplewelcome.jsp。commandClass的类型为LoginBean,在SimpleLoginController中该属性通过onSummit()方法的参数传入。下面是simplewelcome.jsp的代码:
<%@page contentType="text/html;charset=UTF-8"%>
<html>
<head><title>登录成功</title></head>
<%
String str = (String)request.getAttribute("userName");
%>
<body>
<h1>欢迎您!<%=str%></h1>
</body>
</html>
最后在浏览器中输入http://localhost:8080/ch23/ simplelogin.jsp,返回的结果如图23-4所示。
图23-4 simplewelcome.jsp效果图 |
可以看出,simplewelcome.jsp获取了userName的值,然后把它显示在页面上。