标签:
上一篇文章说过要介绍两个控制器。这篇文章就介绍第二个控制器AbstractCommandController(这个类已经快要被废弃了,有更好的代替者,但还是要好好学这个类)。这个控制器的额作用是为了收集提交的参数,
比如说之前的写法是://获取员工的姓名 String username=request.getParameter("username");这样去收集参数,提交的参数一多这样很不方便,所以引入了AbstractCommandController。记住SringMVC中的Action是单例模式,Strut2中的Action是多例模式,所以这就造成了他们收集参数的方式是绝对不同的。
案例如下:
案例结构图:
先给出具体代码实现,在进行讲解。
第一步:先写index.jsp.
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP ‘index.jsp‘ starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/adduser.action" method="post"> <table border="2" align="center"> <tr> <th>姓名</th> <td> <input type="text" name="username" /></td> </tr> <tr> <th>性别</th> <td> <input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" checked/>女 </td> </tr> <!-- <tr> <th>入职时间</th> <td> <input type="text" name="username" /></td> </tr> --> <tr> <td> <input type="submit" value="提交"> </td> </tr> </table> </form> </body> </html>
第二步:写Emp.java,这个文件里面的属性就是要和前面的jsp页面提交的数据要完全吻合(名字必须要一模一样)。就是为了收集页面数据的。
package com.guigu.shen.Action4; public class Emp { //名字(与表单中的name属性必须要一模一样) private String username; //性别 private String gender; /** * @return the username */ /** * */ public Emp() { // TODO Auto-generated constructor stub } public String getUsername() { return username; } /** * @param username the username to set */ public void setUsername(String username) { this.username = username; } /** * @return the gender */ public String getGender() { return gender; } /** * @param gender the gender to set */ public void setGender(String gender) { this.gender = gender; } }
第三步:写EmpAction.java
package com.guigu.shen.Action4; import javax.jws.WebParam.Mode; 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.AbstractCommandController; public class EmpAction extends AbstractCommandController{ /** * 我们知道SpringMvc的Action是单例模式的,所以他收集从页面传过来的参数的方式与Struts2不一样 * SpringMVC能够以实体的形式,收集客户端参数 */ //mvc会走无参的构造器,可以通过里面的代码(this.setCommandClass(Emp.class);),匹配jsp页面中的参数信息 public EmpAction() { //第一步:自动将表单参数封装到Emp对象中 this.setCommandClass(Emp.class); System.out.print("EmpAcion的无参构造函数"); } /* * 参数command表示可以分装好的实体类(Emp) * */ @Override protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { ModelAndView modelAndView=new ModelAndView(); //第二步:command就是Emp对象传进来的。 System.out.println("handle方法"); Emp emp=(Emp) command; modelAndView.addObject("message", "增加员工成功"); System.out.println("员工的名字"+emp.getUsername()); System.out.println("员工的性别"+emp.getGender()); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } }
第四步:springmvc_004.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" > <!-- 控制器(程序员)(必须配置) --> <bean name="/adduser.action" class="com.guigu.shen.Action4.EmpAction"></bean> <!-- 映射器 --> <!-- 适配器 SimpleControllerHandlerAdapter不仅能去找实现了Controller接口的Action 还能去找继承了AbstractCommandController类的Action --> </beans>
第五步:springmvc.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" > <import resource="com/guigu/shen/Action4/springmvc_004.xml"/> </beans>
第六步: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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMvc_10day_self</display-name> <servlet> <!--这个名字可以随便取得,但是这个名字取了之后,以后在 WEB-INF下面创建SpirngMVC的配置文件是,命名必须以这个开头, 所以这里取名叫做DispatcherServlet,那么之后的xml文件取名必须为DispatcherServlet-servlet.xml(一个字都不能差) --> <servlet-name>DispatcherServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 通知DispatcherServlet去指定目录下找到springmvc.xml配置文件 --> <!-- 注意这里的 <param-name>contextConfigLocation</param-name>一个字母都不能有错 一旦有错就会去WEB-INF下面去找 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
运行:输入:http://127.0.0.1:8080/SpringMvc_10day_self/
结果是:正常运行。但是有一个问题。控制台从网页那边得到的中文乱码:
员工的名字?¨???±??±
员工的性别???
先不管这个,我们讲一下这个案例的执行流程:我们要现实的功能其实就是从index.xml页面上输入员工的姓名和性别。然后在EmpAtion中得到这些属性。这里用的是在EmpAction中定义Emp这么一个类,然后由这个类会自动去装配信息。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
好,介绍好流程以后,我们再来解决一下上面的乱码问题。我们以前解决这种问题通常是在EmpAction.java中加一句request.setCharacterEncoding("utf-8");
我们先试试看这样可以吗?试了,答案是不可以。
Spring提供了一个Filter专门用来解决Post提交中文的乱码问题。需要在web.xml中配置。
好,我们按照上面的做法去试试。
修改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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMvc_10day_self</display-name> <!-- Spring提供了一个Filter专门用来解决Post提交中文的乱码问题 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter </filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <!--这个名字可以随便取得,但是这个名字取了之后,以后在 WEB-INF下面创建SpirngMVC的配置文件是,命名必须以这个开头, 所以这里取名叫做DispatcherServlet,那么之后的xml文件取名必须为DispatcherServlet-servlet.xml(一个字都不能差) --> <servlet-name>DispatcherServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 通知DispatcherServlet去指定目录下找到springmvc.xml配置文件 --> <!-- 注意这里的 <param-name>contextConfigLocation</param-name>一个字母都不能有错 一旦有错就会去WEB-INF下面去找 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
输出:员工的名字爱爱
员工的性别女
问题解决了。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
这个问题解决了,我们在加一个功能,在员工的入职日期也加进去。在index.xml中修改代码。如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP ‘index.jsp‘ starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/adduser.action" method="post"> <table border="2" align="center"> <tr> <th>姓名</th> <td> <input type="text" name="username" /></td> </tr> <tr> <th>性别</th> <td> <input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" checked/>女 </td> </tr> <tr> <th>入职时间</th> <td> <input type="text" name="userdata" value="2015-3-2" /></td> </tr> <tr> <td> <input type="submit" value="提交"> </td> </tr> </table> </form> </body> </html>
然后在Emp.java中也修改代码,多一个Data userdata属性。
package com.guigu.shen.Action4; import java.util.Date; public class Emp { //名字 private String username; /** * @return the userdata */ public Date getUserdata() { return userdata; } /** * @param userdata the userdata to set */ public void setUserdata(Date userdata) { this.userdata = userdata; } //性别 private String gender; private Date userdata; /** * @return the username */ /** * */ public Emp() { // TODO Auto-generated constructor stub } public String getUsername() { return username; } /** * @param username the username to set */ public void setUsername(String username) { this.username = username; } /** * @return the gender */ public String getGender() { return gender; } /** * @param gender the gender to set */ public void setGender(String gender) { this.gender = gender; } }
再在EmpAction.java中加一句 System.out.println("員工的入職日誌"+emp.getUserdata().toLocaleString());
package com.guigu.shen.Action4; 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.AbstractCommandController; /* * Create by 沈晓权 * Create on 2016年8月7日下午8:28:10 */ public class EmpAction extends AbstractCommandController{ /** * 我们知道SpringMvc的Action是单例模式的,所以他收集从页面传过来的参数的方式与Struts2不一样 * SpringMVC能够以实体的形式,收集客户端参数 */ //mvc会走无参的构造器,可以通过里面的代码(this.setCommandClass(Emp.class);),匹配jsp页面中的参数信息 public EmpAction() { //第一步:自动将表单参数封装到Emp对象中 this.setCommandClass(Emp.class); System.out.print("EmpAcion的无参构造函数"); } /* * 参数command表示可以分装好的实体类(Emp) * */ @Override protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { ModelAndView modelAndView=new ModelAndView(); //第二步:command就是Emp对象传进来的。 System.out.println("handle方法"); Emp emp=(Emp) command; modelAndView.addObject("message", "增加员工成功"); System.out.println("员工的名字"+emp.getUsername()); System.out.println("员工的性别"+emp.getGender()); System.out.println("員工的入職日誌"+emp.getUserdata().toLocaleString()); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } }
运行之后:结果不行。直接出错。
Request processing failed; nested exception is java.lang.NullPointerException
出错的原因是在收集从index.xml的数据时出错了,导致Emp没有被实例化,然后造成空指针了。
怎么解决呢?
当然,不一定要是yyy-MM-dd这种形式的,是可以改的。
我们修改下代码:
package com.guigu.shen.Action4; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.crypto.Data; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.validation.BindException; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractCommandController; public class EmpAction extends AbstractCommandController{ /** * 我们知道SpringMvc的Action是单例模式的,所以他收集从页面传过来的参数的方式与Struts2不一样 * SpringMVC能够以实体的形式,收集客户端参数 */ //mvc会走无参的构造器,可以通过里面的代码(this.setCommandClass(Emp.class);),匹配jsp页面中的参数信息 public EmpAction() { //第一步:自动将表单参数封装到Emp对象中 this.setCommandClass(Emp.class); System.out.print("EmpAcion的无参构造函数"); } /* * 参数command表示可以分装好的实体类(Emp) * */ @Override protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { ModelAndView modelAndView=new ModelAndView(); //第二步:command就是Emp对象传进来的。 System.out.println("handle方法"); Emp emp=(Emp) command; modelAndView.addObject("message", "增加员工成功"); System.out.println("员工的名字"+emp.getUsername()); System.out.println("员工的性别"+emp.getGender()); System.out.println("員工的入職日誌"+emp.getUserdata().toLocaleString()); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } @Override protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { /*
向springmvc内部注入一个自定义的类型转换器
参数一:将String转换成什么类型的字节码
参数二:自定义转换规则
*/ binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true) ); } }
问题解决了。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
最后我们再实现一个功能:把emp这个类封装到modelAndView。传递给success.jsp然后在success.jsp中把emp里面的数据显示出来。
EmpAction.java改为
/** * Create by 沈晓权 * Create on 2016年8月7日下午8:28:10 */ package com.guigu.shen.Action4; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.crypto.Data; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.validation.BindException; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractCommandController; /* * Create by 沈晓权 * Create on 2016年8月7日下午8:28:10 */ public class EmpAction extends AbstractCommandController{ /** * 我们知道SpringMvc的Action是单例模式的,所以他收集从页面传过来的参数的方式与Struts2不一样 * SpringMVC能够以实体的形式,收集客户端参数 */ //mvc会走无参的构造器,可以通过里面的代码(this.setCommandClass(Emp.class);),匹配jsp页面中的参数信息 public EmpAction() { //第一步:自动将表单参数封装到Emp对象中 this.setCommandClass(Emp.class); System.out.print("EmpAcion的无参构造函数"); } /* * 参数command表示可以分装好的实体类(Emp) * */ @Override protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { ModelAndView modelAndView=new ModelAndView(); //第二步:command就是Emp对象传进来的。 System.out.println("handle方法"); Emp emp=(Emp) command; modelAndView.addObject("message", "增加员工成功"); System.out.println("员工的名字"+emp.getUsername()); System.out.println("员工的性别"+emp.getGender()); System.out.println("員工的入職日誌"+emp.getUserdata().toLocaleString()); modelAndView.addObject("emp", emp); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } /* (non-Javadoc) * @see org.springframework.web.servlet.mvc.BaseCommandController#initBinder(javax.servlet.http.HttpServletRequest, org.springframework.web.bind.ServletRequestDataBinder) */ @Override protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true) ); } }
success.jsp改为:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP ‘index.jsp‘ starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> Success. <br> ${message} 姓名:${requestScope.emp.username }</br> 入职时间:${requestScope.emp.userdata }</br> </body> </html>
运行结果为:增加员工成功 姓名:爱爱
入职时间:Mon Mar 02 00:00:00 CST 2015
发现入职时间这个显示格式不好。我们修改一下success.jsp的代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP ‘index.jsp‘ starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> Success. <br> ${message} 姓名:${requestScope.emp.username }</br> 入职时间:${requestScope.emp.userdata }</br> <!-- 1)fmt:formatDate 来源于http://java.sun.com/jsp/jstl/fmt 2)fmt:formatDate作用是格式化日期的显示。例如2015年5月10号 星期五 3) value表示需要格式化的值 4)typez表示现实的日期,时间都要显示 type=data表示只显示 日期 type=time 表示只显示时间 type=both 时间个日期都要显示 dateStyle="full"这个有好几种格式,看具体的要求 --> 入职时间:<fmt:formatDate value="${requestScope.emp.userdata}" type="date" dateStyle="full" /> </body> </html>
运行结果是:
增加员工成功 姓名:爱爱
入职时间:Mon Mar 02 00:00:00 CST 2015
入职时间:2015年3月2日 星期一
结束。
08SpringMvc_(1)继承AbstractCommandController的Action[能够以实体的形式,收集客户端参数].(2)日期转换器和编码过滤器
标签:
原文地址:http://www.cnblogs.com/shenxiaoquan/p/5747799.html