前面介绍了Spring MVC的概念、搭建Spring MVC运行环境等内容,也介绍了如何在eclipse中建立基于Spring MVC的Mooc项目。本文在Mooc项目的基础上,进一步讨论Spring MVC的视图、模型与控制器,视图与控制器之间的数据交互机制。通过本课的学习,可以达到如下目标。
● 掌握视图、控制器和模型的数据交互机制
● 配置web.xml和spring-servlet文件
Mooc是一个在线编程教育项目,用户学习课程前,需要先注册账号。注册账号流程图如下:
图 1 Mooc项目用户注册账号流程图
在上面的流程图中,Register.jsp和RegisterResult.jsp页面为视图,用于录入用户的注册信息和输出注册结果。RegisterController.java为控制器,对Register.jsp提交的表单进行处理,RegisterController获取表单提交的用户信息并生成用户实体类,最后返回实体类给RegisterResult.jsp页面。
在Spring MVC中要实现上面的用户账号注册业务,需要对Mooc项目做如下改动:
① 新建实体UserInfo类(模型)
② 新建控制器RegisterController类(控制器)
③ 新建Register.jsp页面(视图)
④ 新建RegisterResult.jsp页面(视图)
⑤ 新建spring-servlet配置文件
⑥ 修改web.xml配置文件
关于Mooc项目以及Spring MVC的概念与环境搭建参见《Spring MVC的认知与环境搭建》一文。
1、新建实体类UserInfo类
实体类也称为POJO类,一般放置在项目源代码的POJO目录下。在Mooc项目的src目录下新建com.mooc包,在mooc包下面新建pojo包,在pojo包下新建UserInfo.java类,UserInfo类包含登录账号、登录密码、用户名称属性。
package com.mooc.pojo;
public class UserInfo {
/* 用户登录账号 */
private String login;
/* 用户名称 */
private String name;
/* 登录密码 */
private String password;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}2、新建控制器RegisterController类
RegisterController类为MVC的控制器类,接收和处理视图传递过来的表单数据。控制器类一般放置在项目源代码的controll目录下,在mooc包下面新建controll包,在controll包下新建RegisterController.java类。
控制器类与普通Java类的区别就是在类文件的头部添加了Spring MVC注解@Controller和@RequestMapping。@Controller注解用于标记在一个类上,使用该注解的类就是一个Spring MVC Controller对象,Spring MVC的分发处理器会扫描使用该注解的类,并将视图请求的URL与类中@RequestMapping注解定义的URL进行匹配。
@RequestMapping注解用于处理视图请求地址的映射,该注解可以添加在类或类方法上。添加到类时,需要把该注解添加到类的头部,@Controller注解的后面,表示该类中所有响应请求的方法都是以该地址作为父路径。 添加到类方法时,需要把该注解添加到方法的首部,表示一个处理响应请求的地址。
例如:
@Controller
@RequestMapping("/user")
public class RegisterControll {
@RequestMapping(value="/register.do",method={RequestMethod.GET,RequestMethod.POST})
public ModelAndView registerUser(HttpServletRequest request){
return null;
}
}在上面的案例代码中,@Controller注解添加到类名的头部,让RegisterController类成为MVC控制器类,并在@Controller注解后面添加了@RequestMapping注解,注解传入的参数为“/user”,表示该类将响应请求地址前缀为“/user”的所有视图请求。
RegisterController类的registerUser方法用于处理视图Register.jsp的用户注册请求。Register.jsp要调用registerUser方法,需要知道registerUser方法的请求地址,该请求地址由@RequestMapping注解定义:
@RequestMapping(value="/register.do",method={RequestMethod.GET,RequestMethod.POST})
@RequestMapping注解添加在registerUser方法的首部,其中,value参数给出该方法的请求地址,该请求地址需要和在类头部由@RequestMapping注解定义的地址合并为一个完整的请求地址,例如:"/user/ register.do",method参数给出请求类型。
registerUser方法的传入参数类型为HttpServletRequest,registerUser方法应用HttpServletRequest可以获取客户端请求的所有信息,也包括视图提交的表单信息。registerUser方法返回的类型为ModelAndView,ModelAndView是Spring MVC为视图和控制器方便交换数据而定义的对象,ModelAndView由model和view两部分组成,model用于回传数据,view是视图,通过view可以指定跳转到哪个JSP页面。
RegisterController类代码如下。
package com.mooc.controll;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.mooc.pojo.UserInfo;
@Controller
@RequestMapping("/user")
public class RegisterController {
@RequestMapping(value="/register.do",method={RequestMethod.GET,RequestMethod.POST})
public ModelAndView registerUser(HttpServletRequest request){
/*创建返回的ModelAndView实例*/
ModelAndView view = new ModelAndView();
/*从发送请求的JSP页面获取表单数据*/
String paraLogin = request.getParameter("login");
String paraName = request.getParameter("name");
String paraPsw = request.getParameter("psw");
/*实例化UserInfo模型*/
UserInfo user = new UserInfo();
user.setLogin(paraLogin);
user.setName(paraName);
user.setPassword(paraPsw);
/*添加user模型到view*/
view.addObject("user",user);
/*设置跳转页面*/
view.setViewName("jsp/user/RegisterResult.jsp");
return view;
}
}3 、新建Register.jsp页面
JSP页面在Spring MVC中为视图,是与用户的交互页面,JSP页面一般放置在项目WebContent目录下。在WebContent目录下新建user目录,在user目录下新建Register.jsp文件。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <%String host=request.getContextPath();%> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="<%=host%>/user/register.do" method="post"> <p>登录账号:<input type="text" name="login"/></p> <p>登录密码:<input type="password" name="psw"/></p> <p>昵 称: <input type="text" name="name"/></p> <p> <button type="submit">提交</button></p> </form> </body> </html>
页面form的action路径为在控制器类中由@RequestMapping注解给出的URL路径。
4 、新建RegisterResult.jsp页面
在WebContent目录下的user目录新建RegisterResult.jsp文件,用户注册成功后跳转到RegisterResult.jsp页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<p>注册成功</p>
<p>注册昵称:${requestScope.user.name}</p>
<p>登录账号:${requestScope.user.login}</p>
</body>
</html>使用requestScope可以访问由控制器类返回的模型对象或变量。
5 、新建spring-servlet配置文件
Servlet是用Java语言编写的服务端应用程序,用于响应和处理WEB客户端发送的请求,并生成WEB内容返回WEB客户端。在Spring MVC框架中,控制器类就是Servlet,用于响应和处理WEB客户端发送的请求。Spring MVC会通过spring-servlet配置文件扫描加载控制器类、完成对转向页面的路径解析、启用spring mvc 注解。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 启用spring mvc 注解 --> <context:annotation-config /> <!-- 扫描并加载使用注解的类 --> <context:component-scan base-package="com"></context:component-scan> <!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <mvc:annotation-driven></mvc:annotation-driven> </beans>
6 、修改web.xml配置文件
在web.xml中需要配置Spring MVC的前端控制器DispatchServlet,DispatchServlet在web应用程序启动时立即加载,DispatchServlet会读取spring-servlet配置文件,扫描并加载控制器类,并创建WebApplicationContext容器对象,也就是上下文环境。
<!-- 配置spring MVC servlet --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:\config\spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
配置监听器,当监听到启动Web容器时,自动装配Spring配置文件中的配置信息。
<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:\config\spring.xml</param-value> </context-param>
ContextLoaderListener实现了ServletContextListener接口,WEB容器启动时,会调用ContextLoaderListener,在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。
课程小结
本课实现了基于Spring MVC的用户注册业务,具体业务实现流程是用户通过Register.jsp页面填写注册信息,然后提交表单到RegisterController类,RegisterController类获取表单信息,并创建UserInfo用户类,使用表单信息初始化UserInfo,将UserInfo设置到回传的ModelAndView对象,并将回传的视图定向到RegisterResult.jsp页面。
在上述流程中,Register.jsp是用户注册视图,RegisterResult.jsp是注册结果通知视图,RegisterController是响应和处理注册请求的控制器,UserInfo是用户模型。