1. 程式人生 > >Java進階學習第三十二天(SpringMVC)

Java進階學習第三十二天(SpringMVC)

一、回顧struts2+Spring開發

1、需求:學生註冊【add.jsp > StudentAction.java > addOK.jsp】
① Emp.java

public class Emp {
	private String id;//編號
	private String username;//姓名
	private Double salary;//薪水
	public Emp(){}
	public Emp(String username, Double salary) {
		this.username = username;
		this.salary = salary;
	}
	public String getId() {
		return UUID.randomUUID().toString();
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
}

② JdbcUtil.java

public class JdbcUtil {
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	public static ComboPooledDataSource getDataSource() {
		return dataSource;
	}
}

③ c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
		<property name="jdbcUrl">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
		<property name="user">scott</property>
		<property name="password">tiger</property>
		<property name="acquireIncrement">2</property>
		<property name="initialPoolSize">5</property>
		<property name="minPoolSize">1</property>
		<property name="maxPoolSize">5</property>
	</default-config>
</c3p0-config>

④ EmpDao.java

public class EmpDao {
	/**
	 * 增加員工
	 */
	public void add(Emp emp) throws Exception{
		QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
		String sql = "INSERT INTO EMPS(ID,USERNAME,SALARY) VALUES(?,?,?)";
		Object[] params = {emp.getId(),emp.getUsername(),emp.getSalary()};
		runner.update(sql,params);
	}

	/**
	 * 測試 
	 */
	public static void main(String[] args) throws Exception{
		EmpDao dao = new EmpDao();
		dao.add(new Emp("測試",5000D));
	}
}

⑤ EmpService.java

public class EmpService {
	private EmpDao empDao;
	public void setEmpDao(EmpDao empDao) {//springioc自動注入
		this.empDao = empDao;
	}
	/**
	 * 增加員工
	 */
	public void addEmp(Emp emp) throws Exception{
		if(emp == null){
			throw new RuntimeException("EmpService引數不能為空");
		}
		empDao.add(emp);
	}
}

⑥ EmpAction.java

public class EmpAction extends ActionSupport{
	private EmpService empService;//業務層
	public void setEmpService(EmpService empService) {//springioc自動注入實現類
		this.empService = empService;
	}
	private Emp emp;//模型
	public Emp getEmp() {
		return emp;
	}
	public void setEmp(Emp emp) {
		this.emp = emp;
	}
	/**
	 * 註冊員工
	 */
	public String registerMethod() throws Exception{
		empService.addEmp(emp);
		return "success";
	}
}

2、struts2框架的特點
① 每次請求action時,都會建立action例項
② action類一成不變的直接或間接繼續ActionSupport類
③ action類中的業務控制方法總是相類似的簽名且無參
④ action類中,接收引數要用例項變數和對應的set方法或set/get方法
⑤ struts.xml配置檔案,必須以struts.xml命名,且放在src目錄下
… … …

二、SpringMVC基礎

1、JavaWeb中的MVC設計模式
MVC這種設計模式,不光運用於Web領域,而且也能用於非Web領域;這裡提到的MVC特指一種表現層設計模式,不限於Java語言

2、什麼是springmvc,它與spring有什麼關係
springmvc屬於spring框架的後續產品,用在基於MVC的表現層開發,類似於struts2框架

3、springmvc與struts2的區別
① springmvc的入口是servlet,即前端控制器,例如:*.action;struts2入口是filter過慮器,即前端過濾器,例如:/*
② springmvc是基於方法開發,傳遞引數是通過方法形參,可以設計為單例;struts2是基於類開發,傳遞引數是通過類的屬性,只能設計為多例
③ springmvc通過引數解析器是將request物件內容進行解析成方法形參,以方法引數形式收集值;struts採用值棧儲存請求和響應的資料,以類形式收集值
④ springmvc的結果先繫結在ModelAndView物件中,再放入request域物件中;struts的結果先繫結在ValueStack物件中,再放入request域物件中
⑤ springmvc開發執行速度比struts相對快
……

4、springmvc工作流
① 客戶端發出http請求,只要請求形式符合web.xml檔案中配置的*.action的話,就由DispatcherServlet來處理,然後DispatcherServlet再將http請求委託給對映器的物件,把http請求交給對應的Action來處理
② 對映器根據客戶的http請求,再對比<bean name="/hello.action>,如果匹配正確,再將http請求交給程式設計師寫的Action
③ 執行Action中的業務方法,最終返回一個名叫ModelAndView的物件,其中封裝了向檢視傳送的資料和檢視的邏輯名
④ ModelAndView物件隨著響應到到DispatcherServlet中
⑤ 這時DispatcherServlet收到了ModelAndView物件,它也不知道檢視邏輯名是何意,又得委託一個名叫檢視解析器的物件去具體解析ModelAndView物件中的內容
⑥ 將檢視解析器解析後的內容,再次交由DispatcherServlet核心控制器,這時核心控制器再將請求轉發到具體的檢視頁面,取出資料,再顯示給使用者

5、springmvc快速入門(XML版本)
① 建立springmvc-day01一個web應用
② 匯入springioc,springweb , springmvc相關的jar包
③ 在/WEB-INF/下建立web.xml檔案

    <!-- 註冊springmvc核心控制器 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 通知DispatcherServlet去指定的目錄下載入springmvc.xml配置檔案 -->
		<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>

	<!-- 註冊spring提供的針對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>

④ 建立HelloAction.java控制器類

/**
 * 單例
 * 控制器Action
 * 處理器Action
 */
public class HelloAction implements Controller{
	public HelloAction(){
		System.out.println("HelloAction()::" + this.hashCode());
	}
	/**
	 * 業務方法
	 */
	public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
		System.out.println("HelloAction::handleRequest()");
		/**
		 * ModelAndView表示向檢視封裝的資料和真實路徑
		 */
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message","這是我的第一個springmvc應用程式,對映器_介面卡_檢視解析器_都可省略");
		modelAndView.setViewName("/jsp/success.jsp");
		return modelAndView;
	}
}

⑤ 在/WebRoot/下建立jsp/success.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>這是我的第一個springmvc應用程式</title>
  </head>
  <body>
	success.jsp<br/>
	${message}
  </body>
</html>

⑥ 在/WEB-INF/建立DispatcherServlet-servlet.xml配置檔案,xml頭部資訊與spring.xml相同
注意:該配置檔案的命名規則:web.xml檔案中配置的<servlet-name>的值-servlet.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
        
      ">

	<!-- 控制器(程式設計師) :name表示請求路徑,class表示處理類的全路徑,必選-->
    <bean name="/hello.action" class="cn.itcast.javaee.springmvc.base.HelloAction"></bean>  

    <!-- 對映器(框架):BeanNameUrlHandlerMapping表示將bean標籤的name屬性當做url請求,可選 -->  
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>  
         
    <!-- 介面卡(框架):SimpleControllerHandlerAdapter用於尋找實現了Controller介面的Action類,可選 -->  
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>  
      
    <!-- 檢視解析器(框架) :InternalResourceViewResolver表示ModelAndView物件封裝的檢視名找到真正的頁面,可選-->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>  
</beans>

⑦ 部署web應用到tomcat中,通過瀏覽器訪問URL

6、springmvc快速入門(註解版本)
① 建立springmvc-day02這麼一個web應用
② 匯入springioc,springweb和springmvc相關的jar包

   ------------------------------------------------------springWEB模組
   org.springframework.web-3.0.5.RELEASE.jar
   org.springframework.web.servlet-3.0.5.RELEASE.jar(mvc專用)
   ------------------------------------------------------springIOC模組
   org.springframework.asm-3.0.5.RELEASE.jar
   org.springframework.beans-3.0.5.RELEASE.jar
   org.springframework.context-3.0.5.RELEASE.jar
   org.springframework.core-3.0.5.RELEASE.jar
   org.springframework.expression-3.0.5.RELEASE.jar

③ 在/WEB-INF/下建立web.xml檔案

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  
	<!-- 註冊springmvc核心控制器 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
	
	<!-- 註冊spring核心編碼過濾器 -->
	<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>
	
</web-app>

④ 建立HelloAction.java控制器類

@Controller
public class HelloAction{
	public HelloAction(){
		System.out.println("HelloAction()::" + this.hashCode());
	}
	/**
	 * 業務方法
	 * 只要是/hello.action的請求,都交由HelloAction物件中的hello()方法去處理
	 */
	@RequestMapping(value="/hello.action")   
	public String hello(Model model) throws Exception{
		System.out.println("HelloAction::hello()");
		model.addAttribute("message","你好");
		return "success";
	}
	
	/**
	 * 業務方法
	 * 只要是/bye.action的請求,都交由HelloAction物件中的bye()方法去處理
	 */
	@RequestMapping(value="/bye.action")   
	public String bye(Model model) throws Exception{
		System.out.println("HelloAction::bye()");
		model.addAttribute("message","再見");
		return "success";
	}
}

⑤ 在/WebRoot/下建立success.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
	/ok.jsp<br/>
	成功<br/>
	${message}<br/>
  </body>
</html>

⑥ 在/src/目錄下建立spring.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:mvc="http://www.springframework.org/schema/mvc"
	  xmlns:context="http://www.springframework.org/schema/context"
		
      xsi:schemaLocation="
	
	  http://www.springframework.org/schema/beans 
	  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        
        
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
        
      ">

	<!-- Action,讓springioc容器去掃描帶@Controller的類 -->
	<context:component-scan base-package="cn.itcast.javaee.springmvc.app14"/>
	
	<!-- 檢視解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>      

⑦ 部署web應用到tomcat中,通過瀏覽器訪問URL

三、springmvc.xml檔案

1、載入自定義目錄下的springmvc.xml配置檔案
在預設情況下:springmvc框架的配置檔案必須叫<servlet-name>-servlet.xml
且必須放在/WEB-INF/目錄下,我們可以在web.xml檔案中,為DispatcherServlet配置一個初始化引數,讓它去我們指定的目錄下載入springmvc.xml配置檔案,web.xml程式碼如下:

    <!-- 註冊springmvc框架核心控制器 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/classes/cn/itcast/javaee/springmvc/config/springmvc.xml</param-value>	
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>

如果springmvc.xml配置檔案放在src目錄下,web.xml程式碼如下:

<!-- 註冊springmvc框架核心控制器 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring.xml</param-value>	
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>

2、檢視解析器【作用:解析檢視邏輯名對應的真實路徑】
ModelAndView物件中即可以封裝真實檢視路徑名,也可以封裝檢視路徑的邏輯名

 <!-- 註冊Action(必須配置) -->
      <bean name="/hello.action" class="cn.itcast.javaee.springmvc.app07.HelloAction"></bean> 
      <!-- 
      	如果Action中書寫的是檢視邏輯名稱,那麼檢視解析器就必須配置 
      	如果Action中書寫的是檢視真實名稱,那麼檢視解析器就可選配置 
      -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<!-- 路徑字首 -->
      		<property name="prefix" value="/jsp/"/>
      		<!-- 路徑字尾 -->
      		<property name="suffix" value=".jsp"/>
      		<!-- 字首+檢視邏輯名+字尾=真實路徑 -->
      </bean>
public class HelloAction implements Controller{
	public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message","這是我的第二個springmvc應用程式,檢視使用邏輯名");
		//原來封裝檢視的真實路徑
		//modelAndView.setViewName("/jsp/success.jsp");
		//現在封裝檢視的邏輯名稱
		modelAndView.setViewName("success");
		return modelAndView;
	}
}

3、對映器【作用:把什麼樣的請求交給Action】
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping(核心)
將程式設計師定義的Action所對應的<bean>標籤的name屬性作為請求路徑

      <!-- 註冊控制器(程式設計師) -->
      <bean name="/add.action" class="cn.itcast.javaee.springmvc.mapping.UserAction"></bean>

      <!-- 註冊對映器(handler包)(框架) -->
	  <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
把/delete.action和/update.action和/find.action請求路徑都交由<bean>標籤為id的Action,即多個路徑對應同一個Action

      <!-- 註冊控制器(程式設計師) -->
	  <bean id="userActionID" class="cn.itcast.javaee.springmvc.mapping.UserAction"></bean>
		
	  <!-- 註冊對映器(handler包)(框架) -->
	  <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	  		<property name="mappings">
	  			<props>
	  				<prop key="/delete.action">userActionID</prop>
	  				<prop key="/update.action">userActionID</prop>
	  				<prop key="/find.action">userActionID</prop>
	  			</props>
	  		</property>
	  </bean>

4、介面卡Adapter【作用:找實現了Controller介面的Action】

/**
 * 控制器是實現Controller介面的類
 */
public class EmpAction implements Controller{
	public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
		ModelAndView  modelAndView = new ModelAndView();
		//設定編碼方式
		request.setCharacterEncoding("UTF-8");
		//獲取員工姓名
		String username = request.getParameter("username");
		//顯示
		System.out.println("員工姓名:" + username);
		//將員工姓名封裝到ModelAndView物件中去
		modelAndView.addObject("message",username);
		//將真實路徑名封裝到ModelAndView物件中去
		modelAndView.setViewName("/jsp/success.jsp");
		return modelAndView;
	}
}

5、控制器Controller
org.springframework.web.servlet.mvc.ParameterizableViewController
如果請求是/hello.action的請求路徑,則直接跳轉到/jsp/success.jsp頁面,不經過程式設計師定義的控制器Action

<!-- 專用於jsp到jsp/html的轉發控制器 -->
    <bean name="/index.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    	<!-- 轉發到真實檢視名 -->
    	<property name="viewName" value="/WEB-INF/05_index.jsp"/>
    </bean>

	<!-- 註冊Action -->
	<bean name="/add.action" class="cn.itcast.javaee.springmvc.app10.EmpAction"></bean>
	
	<!-- 對映器 -->
    <!-- 介面卡(SimpleControllerHandlerAdapter去找實現了Controller介面的Action,
    	       也能去找繼承了AbstractCommandController類的Action,...)-->
	<!-- 檢視解析器 -->

</beans>      

org.springframework.web.servlet.mvc.AbstractCommandController
能夠以實體的形式,收集客戶端引數(原因:Action類實現Controller介面,帶來了程式碼耦合;如果引數過多,實現Controller介面的Action收集起來不便)

@SuppressWarnings("deprecation")
public class EmpAction extends AbstractCommandController{
	public EmpAction(){
		//將表單引數封裝到Emp物件中去
		this.setCommandClass(Emp.class);
	}
	/**
	 * 自定義型別轉換器,將String->Date型別(格式yyyy-MM-dd)
	 */
	@Override
	protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
		//向springmvc內部注入一個自定義的型別轉換器
		//引數一:將String轉成什麼型別的位元組碼
		//引數二:自定義轉換規則
		//true表示該日期欄位可以為空
		binder.registerCustomEditor(
				Date.class,
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
	}
	/**
	 * obj表示封裝後的實體
	 * error表示封裝時產生的異常
	 */
	@Override
	protected ModelAndView handle(
			HttpServletRequest request,
			HttpServletResponse response, 
			Object obj, 
			BindException error)throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message","增加員工成功");
		Emp emp = (Emp) obj;
		System.out.println(emp.getUsername()+":"+emp.getGender()+":"+emp.getHiredate().toLocaleString());
		//將Emp封裝到ModeAndView物件中
		modelAndView.addObject("emp",emp);
		modelAndView.setViewName("/jsp/success.jsp");
		return modelAndView;
	}
}

四、SpringMVC細節

1、日期轉換器
在預設情況下,springmvc不能將String型別轉成Date型別,必須自定義型別轉換器

@SuppressWarnings("deprecation")
public class EmpAction extends AbstractCommandController{
	public EmpAction(){
		//將表單引數封裝到Emp物件中去
		this.setCommandClass(Emp.class);
	}
	/**
	 * 自定義型別轉換器,將String->Date型別(格式yyyy-MM-dd)
	 */
	@Override
	protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
		//向springmvc內部注入一個自定義的型別轉換器
		//引數一:將String轉成什麼型別的位元組碼
		//引數二:自定義轉換規則
		//true表示該日期欄位可以為空
		binder.registerCustomEditor(
				Date.class,
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
	}
	/**
	 * obj表示封裝後的實體
	 * error表示封裝時產生的異常
	 */
	@Override
	protected ModelAndView handle(
			HttpServletRequest request,
			HttpServletResponse response, 
			Object obj, 
			BindException error)throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message","增加員工成功");
		Emp emp = (Emp) obj;
		System.out.println(emp.getUsername()+":"+emp.getGender()+":"+emp.getHiredate().toLocaleString());
		//將Emp封裝到ModeAndView物件中
		modelAndView.addObject("emp",emp);
		modelAndView.setViewName("/jsp/success.jsp");
		return modelAndView;
	}
}

success.jsp:

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
	success.jsp<br/>
	成功<br/>
	${requestScope.message}<br/>
	姓名:${requestScope.emp.username}<br/>
	性別:${requestScope.emp.gender}<br/>
	
	入職時間:${requestScope.emp.hiredate}<br/>
	<hr/>
	入職時間:<fmt:formatDate 
				value="${requestScope.emp.hiredate}"
				type="date"
				dateStyle="medium"
			/>
	<!-- 
		1)fmt:formatDate 來源於 http://java.sun.com/jsp/jstl/fmt
		2)fmt:formatDate作用是格式化日期的顯示,例如:2015年5月10日 星期日
		3)value表示需要格式化的值
		4)type表示顯示日期,時間,都顯示
		  type=date表示只顯示日期
		  type=time表示只顯示時間
		  type=both表示日期時間均顯示
		5)dateStyle表示顯示日期的格式:short/medium/default/long/full
	-->
  </body>
</html>

2、編碼過濾器
spring提供的,專用於解決POST提交中文亂碼問題,需要在web.xml檔案中配置

	<!-- 編碼過濾器 -->
	<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>

3、一個Action中,如何寫多個類似的業務控制方法
方法:通過模組根路徑 + 功能子路徑 = 訪問模組下子功能的路徑

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
	<form action="${pageContext.request.contextPath}/user/register.action" method="POST">
		<table border="2" align="center">
			<caption><h2>使用者註冊</h2></caption>
			<tr>
				<th>姓名</th>
				<td><input type="text" name="username"/></td>
			</tr>
			<tr>
				<th>月薪</th>
				<td><input type="text" name="salary" value="7000"/></td>
			</tr>
			<tr>
				<th>入職時間</th>
				<td><input type="text" name="hiredate" value="2015-5-11 12:12:12"/></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="註冊" style="width:111px"/>
				</td>
			</tr>
		</table>	
	</form>	
	
	<hr/>
	
	<form action="${pageContext.request.contextPath}/user/login.action" method="POST">
		<table border="2" align="center">
			<caption><h2>使用者登入</h2></caption>
			<tr>
				<th>姓名</th>
				<td><input type="text" name="username"/></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="登入" style="width:111px"/>
				</td>
			</tr>
		</table>	
	</form>	
  </body>
</html>
@Controller
@RequestMapping(value="/user")
public class UserAction {
	/**
	 * 使用者註冊
	 */
	@RequestMapping(value="/register")
	public String registerMethod(Model model) throws Exception{
		model.addAttribute("message","員工註冊成功");
		return "/jsp/success.jsp";
	}
	/**
	 * 使用者登入
	 */
	@RequestMapping(value="/login")
	public String loginMethod(Model model) throws Exception{
		model.addAttribute("message","員工登入成功");
		return "/jsp/success.jsp";
	}
}

增加使用者:http://127.0.0.1:8080/myspringmvc-day02/user/add.action
查詢使用者:http://127.0.0.1:8080/myspringmvc-day02/user/find.action

4、在業務控制方法中寫入普通變數收集引數
方法:可以在業務控制方法中,以引數形式收集客戶端引數,springmvc採用方法引數形式的

@Controller
@RequestMapping(value="/user")
public class UserAction {
	/**
	 * 使用者註冊
	 */
	@RequestMapping(value="/register")
	public String registerMethod(Model model,String username,String salary) throws Exception{
		System.out.println("使用者註冊-->" + username + ":" + salary);
		model.addAttribute("message","員工註冊成功");
		return "/jsp/success.jsp";
	}
	/**
	 * 使用者登入
	 */
	@RequestMapping(value="/login")
	public String loginMethod(Model model,String username) throws Exception{
		System.out.println("使用者登入-->" + username);
		model.addAttribute("message","員工登入成功");
		return "/jsp/success.jsp";
	}
}

5、限定某個業務控制方法,只允許GET或POST請求方式訪問
方法:可以在業務控制方法前,指明該業務控制方法只能接收GET或POST的請求,如果不書寫method=RequestMethod.POST的話,GET和POST請求都支援

@Controller
@RequestMapping(value="/user")
public class UserAction {
	/**
	 * 使用者註冊,只能接收POST請求
	 */
	@RequestMapping(method=RequestMethod.POST,value="/register")
	public String registerMethod(Model model,String username,String salary) throws Exception{
		System.out.println("使用者註冊-->" + username + ":" + salary);
		model.addAttribute("message","員工註冊成功");
		return "/jsp/success.jsp";
	}
	/**
	 * 使用者登入,即能接收POST請求,又能接收GET請求
	 */
	@RequestMapping(value="/login")
	public String loginMethod(Model model,String username) throws Exception{
		System.out.println("使用者登入-->" + username);
		model.addAttribute("message","員工登入成功");
		return "/jsp/success.jsp";
	}
}

6、在業務控制方法中寫入Request,Response等傳統web引數
方法:可以在業務控制方法中書寫傳統web引數【這種方式不提倡,耦合】

@Controller
@RequestMapping(value="/user")
public class UserAction {
	/**
	 * 使用者註冊,只能接收POST請求
	 */
	@RequestMapping(method=RequestMethod.POST,value="/register")
	public String registerMethod(HttpServletRequest request,HttpServletResponse response) throws Exception{
		//獲取使用者名稱和薪水
		String username = request.getParameter("username");
		String salary = request.getParameter("salary");
		System.out.println("使用者註冊-->" + username + ":" + salary);
		
		//繫結到session域物件中
		request.getSession().setAttribute("username",username);
		request.getSession().setAttribute("salary",salary);
		
		//重定向/jsp/success.jsp頁面
		//response.sendRedirect(request.getContextPath()+"/jsp/success.jsp");
		
		//轉發/jsp/ok.jsp頁面
		request.getRequestDispatcher("/jsp/ok.jsp").forward(request,response);
		
		//轉發(提倡)
		return "/jsp/success.jsp";
	}
}

7、在業務控制方法中寫入模型變數收集引數,且使用@InitBind來解決字串轉日期型別
原因:在預設情況下,springmvc不能將String型別轉成java.util.Date型別,所有我們只能在Action中自定義型別轉換器

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
	/success.jsp<br/>
	成功<br/>
	${user.id}<br/>
	${user.username}<br/>
	${user.salary}<br/>
	
	<fmt:formatDate
		value="${user.hiredate}"
		type="both"
		dateStyle="full"
		timeStyle="default"
	/>
	<br/>
  </body>
</html>
public class User {
	private Integer id = 1;
	private String username;
	private Double salary;
	private Date hiredate;
	public User(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
	@Override
	public String toString() {
		return this.id+":"+this.username+":"+this.salary+":"+this.hiredate.toLocaleString();
	}
}
@Controller
@RequestMapping(value="/user")
public class UserAction {
	/**
	 * 自定義型別轉換器
	 */
	@InitBinder
	public void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(
				Date.class, 
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),true));
	}
	/**
	 * 使用者註冊,只能接收POST請求
	 */
	@RequestMapping(method=RequestMethod.POST,value="/register")
	public String registerMethod(User user,Model model) throws Exception{
		System.out.println("使用者註冊:" + user.toString());
		//將user繫結到model物件中
		model.addAttribute("user",user);
		//轉發到success.jsp頁面
		return "/jsp/success.jsp";
	}
}

8、在業務控制方法中寫入User、Admin多個模型(0個或多個)收集客戶端的引數
方法:
① 如果多個模型中有相同的屬性時,可以用user.name或admin.name來收集客戶端引數
② 用一個新的模型將User和Admin再封裝一次

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body> 
    普通使用者 
	<form action="${pageContext.request.contextPath}/person/register.action" method="POST">
		<table border="2" align="center">
			<tr>
				<th>姓名</th>
				<td><input type="text" name="user.username" value="${user.username}"/></td>
			</tr>
			<tr>
				<th>月薪</th>
				<td><input type="text" name="user.salary" value="${user.salary}"></td>
			</tr>
			<tr>
				<th>入職時間</th>
				<td><input 
						type="text" 
						name="user.hiredate" 
						value='<fmt:formatDate value="${user.hiredate}" type="date" dateStyle="default"/>'/></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="普通使用者註冊" style="width:111px"/>
				</td>
			</tr>
		</table>	
	</form>	

	<hr/>

	管理員
	<form action="${pageContext.request.contextPath}/person/register.action" method="POST">
		<table border="2" align="center">
			<tr>
				<th>姓名</th>
				<td><input type="text" name="admin.username" value="${admin.username}"/></td>
			</tr>
			<tr>
				<th>月薪</th>
				<td><input type="text" name="admin.salary" value="${admin.salary}"/></td>
			</tr>
			<tr>
				<th>入職時間</th>
				<td><input type="text" name="admin.hiredate" value='<fmt:formatDate value="${admin.hiredate}" type="date" dateStyle="default"/>'/></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="管理員註冊" style="width:111px"/>
				</td>
			</tr>
		</table>	
	</form>	
  </body>
</html>
/**
 * 封裝User和Admin的物件
 */
public class Bean {
	private User user;
	private Admin admin;
	public Bean(){}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public Admin getAdmin() {
		return admin;
	}
	public void setAdmin(Admin admin) {
		this.admin = admin;
	}
}
@Controller
@RequestMapping(value="/person")
public class PersonAction {
	@InitBinder
	public void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(
				Date.class, 
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
	}

	// 業務方法
	@RequestMapping(value="/register")
	public String registerMethod(Bean bean,Model model) throws Exception{
		System.out.println("普通使用者:" + bean.getUser());
		System.out.println("管理員:" + bean.getAdmin());
		//將user和admin都繫結到Model
		model.addAttribute("user",bean.getUser());
		model.addAttribute("admin",bean.getAdmin());
		//轉發
		return "/02_person.jsp";
	}
}

9、在業務控制方法中收集陣列引數【例如:批量刪除使用者】

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body> 
    <form action="${pageContext.request.contextPath}/emp/deleteAll.action" method="POST">
    	<table border="2" align="center">
    		<tr>
    			<th>編號</th>
    			<th>姓名</th>
    		</tr>
    		<tr>
    			<td><input type="checkbox" name="ids" value="1"/></td>
    			<td>哈哈</td>
    		</tr>
    		<tr>
    			<td><input type="checkbox" name="ids" value="2"/></td>
    			<td>呵呵</td>
    		</tr>
    		<tr>
    			<td><input type="checkbox" name="ids" value="3"/></td>
    			<td>嘻嘻</td>
    		</tr>
    		<tr>
    			<td><input type="checkbox" name="ids" value="4"/></td>
    			<td>笨笨</td>
    		</tr>
    		<tr>
    			<td><input type="checkbox" name="ids" value="5"/></td>
    			<td>聰聰</td>
    		</tr>
    		<tr>
    			<td>
    				<input type="submit" value="刪除"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
	@RequestMapping(value="/deleteAll",method=RequestMethod.POST)
	public String deleteAll(Model model,int[] ids) throws Exception{
		System.out.println("需要刪除的員工編號分別是:");
		for(int id : ids){
			System.out.print(id+" ");
		}
		model.addAttribute("message","批量刪除員工成功");
		return "/jsp/ok.jsp";
	}
}

10、在業務控制方法中收集List<JavaBean>引數【例如:批量註冊使用者】

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body> 
    <form action="${pageContext.request.contextPath}/emp/addAll.action" method="POST">
    	<table border="2" align="center">
    		<caption><h2>批量註冊員工</h2></caption>
    		<tr>
    			<td><input type="text" name="empList[0].username" value="哈哈"/></td>
    			<td><input type="text" name="empList[0].salary" value="7000"/></td>
    		</tr>
    		<tr>
    			<td><input type="text" name="empList[1].username" value="呵呵"/></td>
    			<td><input type="text" name="empList[1].salary" value="7500"/></td>
    		</tr>
    		<tr>
    			<td><input type="text" name="empList[2].username" value="班長"/></td>
    			<td><input type="text" name="empList[2].salary" value="8000"/></td>
    		</tr>
    		<tr>
    			<td><input type="text" name="empList[3].username" value="鍵狀哥"/></td>
    			<td><input type="text" name="empList[3].salary" value="8000"/></td>
    		</tr>
    		<tr>
    			<td><input type="text" name="empList[4].username" value="綠同學"/></td>
    			<td><input type="text" name="empList[4].salary" value="9000"/></td>
    		</tr>
    		<tr>
    			<td colspan="2" align="center">
    				<input type="submit" value="批量註冊"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>
public class Emp {
	private String username;//姓名
	private Double salary;//薪水
	public Emp(){}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
}

/**
 * 封裝多個Emp的物件 
 * @author AdminTC
 */
public class Bean {
	private List<Emp> empList = new ArrayList<Emp>();
	public Bean(){}
	public List<Emp> getEmpList() {
		return empList;
	}
	public void setEmpList(List<Emp> empList) {
		this.empList = empList;
	}
}
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
	/**
	 * 批量新增員工
	 */
	@RequestMapping(value="/addAll",method=RequestMethod.POST)
	public String addAll(Model model,Bean bean) throws Exception{
		for(Emp emp:bean.getEmpList()){
			System.out.println(emp.getUsername()+":"+emp.getSalary());
		}
		model.addAttribute("message","批量增加員工成功");
		return "/jsp/ok.jsp";
	}
}

11、結果的轉發和重定向
在轉發情況下,共享request域物件,會將引數從第一個業務控制方法傳入第二個業務控制方法;反之,重定向則不行

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body> 
    
    1 哈哈 7000
    &nbsp;&nbsp;&nbsp;&nbsp;
    <a href="${pageContext.request.contextPath}/emp/find.action?id=1" style="text-decoration:none">編輯</a>
    
  </body>
</html>
@Controller
@RequestMapping(value="/emp")				
public class EmpAction {
	@RequestMapping(value="/find")
	public String findEmpById(int id,Model model) throws Exception{
		System.out.println("查詢"+id+"號員工資訊");
		//轉發到EmpAction的另一個方法中去,即再次傳送請求
		return "forward:/emp/update.action";
		//重定向到EmpAction的另一個方法中去,即再次傳送請求
		//return "redirect:/emp/update.action?id=" + id;
	}

	@RequestMapping(value="/update")
	public String updateEmpById(int id,Model model) throws Exception{
		System.out.println("更新" + id +"號員工資訊");
		model.addAttribute("message","更新員工資訊成功");
		return "/jsp/ok.jsp";
	}
}

12、非同步傳送表單資料到JavaBean並響應JSON文字返回到瀏覽器
方法步驟:
① 匯入jackson-core-asl-1.9.11.jar和jackson-mapper-asl-1.9.11.jar
② 在業務方法的返回值和許可權之間使用@ResponseBody註解表示返回值物件需要轉成JSON文字
③ 在spring.xml配置檔案中編寫如下程式碼:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
				<property name="messageConverters">
						<list>
							<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
						</list>
				</property>
		    </bean>
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  	<script type="text/javascript" src="js/jquery-1.8.2.js"></script>
  </head>
  <body> 

   <input type="button" value="Emp轉JSON"/><p>
   <input type="button" value="List<Emp>轉JSON"/><p>
   <input type="button" value="Map<String,Object>轉JSON"/><p>

   <!-- Map<String,Object>轉JSON -->	  
   <script type="text/javascript">
   		$(":button:last").click(function(){
   			var url = "${pageContext.request.contextPath}/emp/map2json.action";
   			var sendData = null;
			$.post(url,sendData,function(backData,textStaut,ajax){
				alert(ajax.responseText);
			});		
   		});
   </script>

   <!-- List<Emp>轉JSON -->	  
   <script type="text/javascript">
   		$(":button:eq(1)").click(function(){
   			var url = "${pageContext.request.contextPath}/emp/listbean2json.action";
   			var sendData = null;
			$.post(url,sendData,function(backData,textStaut,ajax){
				alert(ajax.responseText);
			});		
   		});
   </script>
   
   <!-- Emp轉JSON -->	  
   <script type="text/javascript">
   		$(":button:first").click(function(){
   			var url = "${pageContext.request.contextPath}/emp/bean2json.action";
   			var sendData = null;
			$.post(url,sendData,function(backData,textStaut,ajax){
				//alert(ajax.responseText);
				var hiredate = backData.hiredate;
				var date = new Date(hiredate);
				alert(date.getFullYear()+"年"+(date.getMonth()+1)+"月"+(date.getDate())+"日");
			});		
   		});
   </script>
  </body>
</html>
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
	/**
     * @ResponseBody Emp 表示讓springmvc將Emp物件轉成json文字
	 */
	@RequestMapping(value="/bean2json")
	public @ResponseBody Emp bean2json() throws Exception{
		//建立Emp物件
		Emp emp = new Emp();
		emp.setId(1);
		emp.setUsername("哈哈");
		emp.setSalary(7000D);
		emp.setHiredate(new Date());
		return emp;
	}
	
	@RequestMapping(value="/listbean2json")
	public @ResponseBody List<Emp> listbean2json() throws Exception{
		//建立List物件
		List<Emp> empList = new ArrayList<Emp>();
		//向List物件中新增三個Emp物件
		empList.add(new Emp(1,"哈哈",7000D,new Date()));
		empList.add(new Emp(2,"呵呵",8000D,new Date()));
		empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
		//返回需要轉JSON文字的物件
		return empList;
	}

	
	@RequestMapping(value="/map2json")
	public @ResponseBody Map<String,Object> map2json() throws Exception{
		//建立List物件
		List<Emp> empList = new ArrayList<Emp>();
		//向List物件中新增三個Emp物件
		empList.add(new Emp(1,"哈哈",7000D,new Date()));
		empList.add(new Emp(2,"呵呵",8000D,new Date()));
		empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
		//建立Map物件
		Map<String,Object> map = new LinkedHashMap<String,Object>();
		//向Map物件中繫結二個變數
		map.put("total",empList.size());
		map.put("rows",empList);
		//返回需要轉JSON文字的物件
		return map;
	}
}
<?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:mvc="http://www.springframework.org/schema/mvc"
	  xmlns:context="http://www.springframework.org/schema/context"
		
      xsi:schemaLocation="
	
	  http://www.springframework.org/schema/beans 
	  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        
        
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
        
      ">

		<!-- EmpAction類  -->
		<context:component-scan base-package="cn.itcast.javaee.springmvc.app25"/>

		<!-- 註冊介面卡 -->
		<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
				<property name="messageConverters">
						<list>
							<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
						</list>
				</property>
		</bean>
</beans>      

五、員工管理系統(springmvc + spring + jdbc + oracle)

1、Emp.java(JavaBean的屬性用包裝型別:Integer、Double;普通方法的引數型別用基礎型別:int、double)

public class Emp {
	private String id;//編號
	private String username;//姓名
	private Double salary;//薪水
	private Date hiredate;//入職時間
	public Emp(){}
	public String getId() {
		return UUID.randomUUID().toString();
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
}
public class Emp {
	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Date hiredate;
	private Integer sal;
	private Integer comm;
	private Integer deptno;
	public Emp(){}
	public Integer getEmpno() {
		return empno;
	}
	public void setEmpno(Integer empno) {
		this.empno = empno;
	}
	public String getEname() {
		return ename;
	}
	public void setEname(String ename) {
		this.ename = ename;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Integer getMgr() {
		return mgr;
	}
	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
	public Integer getSal() {
		return sal;
	}
	public void setSal(Integer sal) {
		this.sal = sal;
	}
	public Integer getComm() {
		return comm;
	}
	public void setComm(Integer comm) {
		this.comm = comm;
	}
	public Integer getDeptno() {
		return deptno;
	}
	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}
}

2、JdbcUtil.java

public class JdbcUtil {
	// 去src目錄下載入c3p0-config.xml配置檔案
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	// 獲取資料來源
	public static ComboPooledDataSource getDataSource() {
		return dataSource;
	}
}

3、c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
		<property name="jdbcUrl">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
		<property name="user">scott</property>
		<property name="password">tiger</property>
		<property name="acquireIncrement">2</property>
		<property name="initialPoolSize">5</property>
		<property name="minPoolSize">1</property>
		<property name="maxPoolSize">5</property>
	</default-config>
</c3p0-config>

4、EmpDao.java

/**
 * 員工管理模組
 * 持久層實現類
 */
public class EmpDao {
	// 增加員工
	public void add(Emp emp) throws Exception{
		QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
		String sql = "insert into emps(id,username,salary,hiredate) values(?,?,?,?)";
		Object[] params = {emp.getId(),emp.getUsername(),emp.getSalary(),emp.new Timestamp(getHiredate()).getTime()};
		runner.update(sql,params);
	}

	public static void main(String[] args) throws Exception{
		Emp emp = new Emp();
		emp.setId("a140a519-6168-4a97-a753-5c5e5cf0a8b2");
		emp.setUsername("哈哈");
		emp.setSalary(7000D);
		String year = "15";
		String month = "5月";
		String date = "10";
		String str = date+"-"+month+"-"+year;
		DateFormat df = new SimpleDateFormat("dd-MM-yy");
		emp.setHiredate(df.parse(str));
		EmpDao dao = new EmpDao();
		dao.add(emp);	
	}
}
@Component("empDao")
public class EmpDao {
	/**
	 * 查詢所有員工
	 */	
	public List<Emp> findAll() throws Exception{
		QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
		String sql = "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO FROM EMP";
		return runner.query(sql,new BeanListHandler<Emp>(Emp.class));
	}	

	@Test
	public void testFindAll() throws Exception{
		EmpDao dao = new EmpDao();
		for(Emp emp : dao.findAll()){
			System.out.println(emp.getEmpno()+":"+emp.getEname()+":"+emp.getSal());
		}
	}
}

5、EmpService.java

/**
 * 員工管理模組
 * 業務層實現類
 */
public class EmpService {
	private EmpDao empDao;
	public void setEmpDao(EmpDao empDao) {
		this.empDao = empDao;
	}
	// 增加員工
	public void register(Emp emp) throws Exception{
		empDao.add(emp);
	}
}
@Component("empService")
public class EmpService {
	private EmpDao empDao;
	@Resource(name="empDao")
	public void setEmpDao(EmpDao empDao) {
		this.empDao = empDao;
	}
	
	// 查詢所有員工
	public List<Emp> findAllEmp() throws Exception{
		return empDao.findAll();
	}
}

6、EmpAction.java

/**
 * 員工管理模組
 * 控制器
 */
@SuppressWarnings("deprecation")
public class EmpAction extends AbstractCommandController{
	//業務層
	private EmpService empService;
	public void setEmpService(EmpService empService) {
		this.empService = empService;
	}
	//將表單引數封裝到Emp實體中
	public EmpAction(){
		this.setCommandClass(Emp.class);
	}
	//自定義String到Date的轉換器
	@Override
	protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(
				Date.class, 
				new CustomDateEditor(new SimpleDateFormat("dd-MM-yy"),true));
	}
	@Override
	protected ModelAndView handle(
			HttpServletRequest request,
			HttpServletResponse response, 
			Object obj, 
			BindException error)
			throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		Emp emp = (Emp) obj;
		System.out.println(emp.getHiredate().toLocaleString());
		empService.register(emp);
		modelAndView.addObject("message","操作成功");
		modelAndView.setViewName("success");
		return modelAndView;
	}
}
@Controller
@RequestMapping("/emp")
public class EmpAction{ 
	private EmpService empService;
	@Resource(name="empService")
	public void setEmpService(EmpService empService) {
		this.empService = empService;
	}
	
	/**
	 * 查詢所有的員工
	 */
	@RequestMapping("/findAllEmpMethod")
	public @ResponseBody Map<String,Object> findAllEmpMethod() throws Exception{
		//呼叫業務層,返回List物件
		List<Emp> empList = empService.findAllEmp();
		//建立Map物件
		Map<String,Object> map = new LinkedHashMap<String,Object>();
		//封裝DataGrid需要的二個引數
		map.put("total",empList.size());
		map.put("rows",empList);
		//返回需要轉成JSON文字的物件
		return map;
	}
}

7、web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- 註冊springmvc核心控制器 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

	<!-- 註冊針對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>
</web-app>

8、spring.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: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/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        
      ">
      
      <import resource="cn/itcast/emp/config/spring-emp.xml"/>
</beans>    

9、spring-emp.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: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/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        
      ">
      
      <!-- 註冊EmpDao類 -->
      <bean id="empDaoID" class="cn.itcast.emp.dao.EmpDao"></bean>

      <!-- 註冊EmpService類 -->
      <bean id="empServiceID" class="cn.itcast.emp.service.EmpService">
      		<property name="empDao" ref="empDaoID"/>
      </bean>
      
	  <!-- 註冊Action -->
      <bean name="/add.do" class="cn.itcast.emp.action.EmpAction">
      	<property name="empService" ref="empServiceID"/>
      </bean>	
	  <!-- 對映器 -->	      
	  <!-- 介面卡 -->
	  <!-- 檢視解析器 -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<property name="prefix" value="/"/>
      		<property name="suffix" value=".jsp"/>
      </bean>
</beans>      
<?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:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
		
      xsi:schemaLocation="
	
	  http://www.springframework.org/schema/beans 
	  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      
        
      ">

    <!-- 註冊介面卡 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name="messageConverters">
    		<list>
    			<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    		</list>
    	</property>
    </bean>

	<!-- 註冊EmpAction -->
	<context:component-scan base-package="cn.itcast.emp"/>	    

	<!--讓springioc容器去解析@Resource這些解的含義,可省 
    	<context:annotation-config/>
    -->
</beans>  

10、index.jsp

<html>
  <head>
    <title>員工管理系統</title>
  </head>
  <body>
		<form action="${pageContext.request.contextPath}/add.do" method="POST">
		<table border="2" align="center">
			<tr>
				<th>姓名</th>
				<td><input type="text" name="username"/></td>				
			</tr>
			<tr>
				<th>期望薪水</th>
				<td>
					<input type="text" name="salary" value="7000"/>
				</td>				
			</tr>
			<tr>
				<th>入職時間</th>
				<td>
					<input type="text" name="hiredate" value="2015-5-10"/>
				</td>				
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="提交"/>
				</td>
			</tr>
		</table>
	</form>
  </body>
</html>

11、success.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
	/success.jsp<br/>
	${requestScope.message}<br/>
  </body>
</html>

12、empList.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  		<link rel="stylesheet" href="${pageContext.request.contextPath}/themes/default/easyui.css" type="text/css"></link>
  		<link rel="stylesheet" href="${pageContext.request.contextPath}/themes/icon.css" type="text/css"></link>
  		<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
  		<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.easyui.min.js"></script>
  		<script type="text/javascript" src="${pageContext.request.contextPath}/js/easyui-lang-zh_TW.js"></script>
  </head>
  <body>
	<table id="dg"></table>
	<script type="text/javascript">
		$("#dg").datagrid({
			url : "${pageContext.request.contextPath}/emp/findAllEmpMethod.do?time="+new Date().getTime(),
			columns:[[    
		        {field:'empno',title:'編號',width:100},    
		        {field:'ename',title:'姓名',width:100},    
		        {field:'job',title:'職位',width:100},   
		        {field:'mgr',title:'上級編號',width:100},   
		        {field:'hiredate',title:'入職時間',width:100,
		        	formatter:function(value){
		        		var date = new Date(value);
		        		var year = date.getFullYear();
		        		var month = date.getMonth()+1;
		        		var date = date.getDate();
		        		return year+"年"+month+"月"+date+"日";
		        	}
		        },    
		        {field:'sal',title:'薪水',width:100},  
		        {field:'comm',title:'佣金',width:100,
		        	formatter:function(value){
		        		if(value == null){
		        			return 0;
		        		}else{
		        			return value;
		        		}
		        	}
		        },