结合springmvc学习(一)和(二),我们可以让服务器启动时,首先访问hello.jsp,然后页面提交后到TestController中,接着返回到hello.jsp页面。项目结构如下:
配置如下:
①web.xml中配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>指定配置文件路径</description>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<!-- 服务器启动时创建该servlet实例 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>hello.do</welcome-file>
</welcome-file-list>
</web-app>
②applicationContext.xml中配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
classpath:/org/springframework/context/config/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
classpath:/org/springframework/web/servlet/config/spring-mvc-3.2.xsd ">
<!-- 根据我们请求的不同来选择调用相对应的controller -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="testController.do">testController</prop>
<prop key="hello.do">urlPageDirect</prop>
</props>
</property>
</bean>
<bean id="urlPageDirect" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
<bean id="testController" class="com.zhongqian.controller.TestController"></bean>
<!-- 视图解析器,用来指定返回后的页面 .如返回aa,则对于的页面为/WEB-INF/jsp/aa.jsp -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<!-- 返回的视图模型数据需要经过jstl来处理 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
③hello.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>
<form method="post" action="testController.do">
employeeID:<input type="text" name="empId"/><br/>
empName:<input type="text" name="empName"/><br/>
empAge:<input type="text" name="empAge"/><br/>
emphireDate:<input type="text" name="empHireDate"/><br/>
<input type="submit" value="submit"/> <input type="reset" value="cancel"/>
</form>
</body>
</html>
④TestController代码如下:
public class TestController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
String name = arg0.getParameter("empName");
System.out.println(name);
return new ModelAndView("hello");
}
}
启动项目后页面显示如下:
暂且只输入empName(后台现在只对empName的值进行了接收),然后点击submit提交,后台打印输入的内容。
由后台可知,是通过request.getParameter("name")来接收数据的,当表单数据过多时,这种方式显然不够好。现在TestController进行改进,如下:
public class TestController extends AbstractCommandController{
@Override
protected ModelAndView handle(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, BindException arg3)
throws Exception {
Employee emp = (Employee)arg2;
System.out.println(emp);
return new ModelAndView("hello");
}
}
Employee类代码如下:
public class Employee {
private int empId;
private String empName;
private int empAge;
private Date emphireDate;
@Override
public String toString() {
return empId+" ,"+empName+", "+empAge;
}
。。。//get/set方法省略
}
对于页面hello.jsp,表单中name属性值要与employee对象属性名称一致,这里先要将empHiredate的name属性去掉,避免报错,后面会讲到解决方案。现在问题是,表单提交时,对象封装到改进后的TestController中handler方法的第二个参数,那么spring在进行封装时,是如何知道arg2对于的对象是Employee呢?因此在创建TestController对应的bean时,要作如下改动:
<bean id="testController" class="com.zhongqian.controller.TestController">
<property name="commandClass" value="com.zhongqian.entities.Employee" />
</bean>
这是重新发布项目,输入id,age,name三个输入框后提交,在后台会打印输入的数据。说明数据成功封装到了arg2中。
下面来处理对于最后一个输入框empHireDate的处理,将它的name属性添加上,运行输入数据后,提交将出现一个奇怪的结果无论输入什么emphireDate的值都为空!这是为什么?在spring进行数据封装即数据绑定时,提交到后台的数据都是String类型,对于基本的数据类型会自动的进行转化,即将String类型转化int,float等。但是当我们对int的数据类型输入时,输入的不是全数字,这个时候转化就会失败,但是程序并不报错,而是将对应的值设为0,即取其默认值.
那么如何解决输入时间的为空的问题呢?这个时候我们就要自定义属性编辑器了!这里我们就不自定义了属性编辑器了,使用springmvc提供一个自定义时间编辑器。接着就要使用这个编辑器了,在TestController中重写initBinder方法。如下:
@Override
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
System.out.println("oooo");
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
配置好后,重启发布,不知道为何,我这里还是为null。╮(╯▽╰)╭。。。。这里不再深究了。应为在spring3.0后,已经不推荐这样做了,这里学习只是为了更好理解springmvc。
除了AbstractCommandController外,spring还提供了FormController来对表单数据进行封装。那么两者之间有什么不同呢?请看如下:
创建一个TestFormController如下:
public class TestFormController extends SimpleFormController {
//用于将页面需要的数据传送到页面
protected Map referenceData(HttpServletRequest request) throws Exception {
Map<String,String[]> map = new HashMap<String,String[]>();
map.put("deptList", new String[]{"sale","oa","it"});
return map;
}
@Override
protected ModelAndView onSubmit(Object command) throws Exception {
Employee emp = (Employee)command;
System.out.println(emp);
return new ModelAndView(getSuccessView());
}
@Override
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
}
对应bean的配置:
<bean id="testFormController" class="com.zhongqian.controller.TestFormController">
<property name="commandClass" value="com.zhongqian.entities.Employee" />
<property name="formView" value="hello"/>
<property name="successView" value="hello"/>
</bean>
另外在handlerMapping需要添加
<prop key="testFormController.do">testFormController</prop>
当用户以get请求访问testFormController.do时,会直接跳转到formView对应的视图。并且在跳转到视图前,会调用reffrenceData方法,将页面需要的数据传送到页面。当用于以Post请求时,则会调用onSubmit()方法。
修改hello.jsp页面使用jstl标签,显示如下:
输入正确数据后提交,后台打印相应的信息。