。別類
    的當適用使求需的己自依以可您讓,構架承繼
Controller                                            Controller
的善完個一了供提還    ,外之架框       供提了除
                      Spring              Web MVC
             。便方為更上合整的能功多許在,能功器
容 的
  IoC    合結,題問架框
         Spring             的存現決解能望希,案
                               Web MVC
方架框       的己自供提也
        Web MVC         ,)     S pring(架框F ramework        MVC
  的 案 專)
Web           (碼 始 原 放 開 多 許 有 今 現 , 構 架 的 薦 推 所
             O penSource
員人發開數多受 ,時式程用應 發開來以久長是構架   Web                        Web MVC
                  Spring Web MVC 框架
      7
Spring 2.0   良信林(冊手術技            – http://openhome.cc     )

  7.1 Spring Web MVC 入門
        的單簡最個一從將,中節小個這在                              解了來,式程用應
                                              Spring Web                     Web
  MVC   的    及以,式方作運的構架           Spring    Web   。構架     現實何如架框Web MVC



  7.1.1 使用 Eclipse Web Tools Platform

              用使將,式程用應 的章本
               Web                         Eclipse Web Tools Platform   (   W TP   )
  「的               在以可您,發開行進來
                           http://www.eclipse.org/webtools/        d ownloads      」
  用使將章本。本版的」             「載下區
            W ebTools Platform; All-in-one                         Tomcat 5.5
         至請也以所,)
        Servlet      (器容   為作
                        C ontainer                   http://tomcat.apache.org/
        Tomcat 5.5    。    載下

             用使算打果如     Eclipse   裝安式方新更上線的          WTP   下 考 參 以 可 則,
          :學教音影的址網列
          http://eclipse.cdpa.nsysu.edu.tw/technology/phoenix/demos/i
          nstall-wtp/install-wtp.html



  寫撰了為,後之 行執在  WTP                      Web   的便方些一用使以可,時式程用應
      「行執 請 , 合 組 窗 視 具 工                     啟開擇選,」
                             W indow/Open Perspective/Other…
     :」
      J 2EE Perspective 「




7 2
Chapter 7 Spring Web MVC     架框




                       圖   7.1   啟開擇選      J2EE Perspective


   動啟接直中 在以可就此如,境環行執
              Server               定設要先首              WTP             Tomcat
選方下窗視 在請,式程用應 的寫撰所中 在試測以,器容
              WTP                     Web                     WTP
    :」   「行執 , 鍵 右 鼠 滑 按 中 窗 視 於 並 , 」
   S ervers                              「擇           N ew/Server




                           圖   7.2   增新   Server   境環行執
用使將章本為因           Tomcat 5.5         「在著接以所,          N ew Server   擇選中窗視」
 「的中」
 A pache「       T omcat v5.5 Server     :」




                                                                          7 3
7 4
                               :                                        FirstSpringMVC
為稱名案專            Spring Web MVC
                個一第設假,稱名案專入輸,後之鈕按
     N ext
」 「下按在,案專」                   W eb/Dynamic Web Project
                             「擇選,時案專增新
」   F ile/New/Project…
        「行執 在 以 可 , 式 程 用 應 寫 撰 要 中 在                      Web             WTP
                          境環行執    Server   了增新       7.4   圖
                : 示 所 圖 下 如 後成完 , 增 新 的 境 環 行 執 成完可即,鈕按        Server
」   F inish   「下按著接,夾料資裝安         Tomcat
                                      擇選請,後之鈕按」 「下按                     N ext
                            型類   Server   定設   7.3   圖
                    )   – http://openhome.cc          良信林(冊手術技              Spring 2.0
Chapter 7 Spring Web MVC      架框




                    圖   7.5   態動增新       Web   案專
理管源資了為次這。增新的案專成完可即,後之鈕按」 「下按
     F inish
,          的依相其及以,     用使接直,便方的上
                spring.jar                      commons-logging.jar
     jar    。下夾料資      到放 個兩這將請
               WEB-INF/lib




                    圖   7.6   態動   Web   構結案專




                                                                      7
Spring 2.0    良信林(冊手術技          – http://openhome.cc       )

  式程用應   在置放須必是或,案檔碼始原
           WTP            的中
                         Java        在                           Web
  資關相 或頁網它其,下之錄目 在增新以可,案檔的下
  Classpath                            src                         Web
     為)  (出匯要後以,下之錄目         在增新以可,源
                    WebContent                                E xport       WAR
    為織組案檔關相將動自會 ,時案檔)
      W eb Application Archive           (   W TP                            Web
                     。 構結統 系 案 檔 的 式 程 用 應

  7.1.2 第一個 Spring Web MVC 程式

  先須 必 而 , 源 資 的 需 所至接 連 接 直 不 並 者 用 使 , 中 構 架
          Web MVC                                       在
  求請的 者 用 使 斷 判 器 制 控 端 前 由 , )
                         F ront controller   ( 器 制控 端前至接連
  達 此藉 ,求 請 理 處 來)
            D ispatch       (件 物 制 控 個 一 哪 給 )        (派 分 要
                                               C ontroller
                                    。 的 目 之源資 求 請 者 用 使 制 控 到
           是的色角器制控端前任擔,中架框
          Spring    Web MVC                     的       在           org.spring-
  將責負
  framework.web.servlet.DispatcherServlet
                       ,                             D ispatcherServlet
  是就,步一第的                     用 使 以 所 , 件 物制控 給 配 分 求 請 的 戶 客
                                              Spring Web MVC
      web.xml                 :
                        DispatcherServlet      義定中          在
      FirstSpringMVC                                                      web.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    → http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

        <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>




7 6
Chapter 7 Spring Web MVC        架框

       <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/mvc-config.xml</param-value>
           </init-param>
           <load-on-startup>1</load-on-startup>
       </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>



      例實的  web.xml       個一了義定中             在
                                       DispatcherServlet       "dispatcher-
由會都求請的尾結
Servlet"      至接連有所,到看以可中定設從,                      *.do
定設來用數參始初
"dispatcherServlet"          ,理處來
                             " contextConfigLocation"
參始初
Bean                置設不果如,稱名與置位的檔義定         "contextConfigLocation"
    「取讀,置前為稱名的         用使會設預
         DispatcherServlet                  則,數
                                        Servlet                       S ervlet
取讀會則中定設的面上在,檔義定
       - servlet.xml         其為作」
                                Bean         稱名
mvc-config.xml               。義定的中
           :是 像 , 源 來 的 檔 義 定 個 多 義 定 以 可 也 您
                         Bean


...
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-config.xml,



                                                                            7 7
Spring 2.0   良信林(冊手術技            – http://openhome.cc   )

              → /WEB-INF/other-service.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  ...


    (件物制控至求請配分責負
       DispatcherServlet                            C ontroller   在,)   Spring
  Web MVC 作實要件物制控,中架框                     org.springframework.web.servlet.
  的作實須必個一有面介
  mvc.Controller ,面介       C ontroller                      handleRequest()
               :示所 下 如 義 定 其 , 法 方
  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;
  }

         行執會,求請的配分
          Controller                到收
                              DispatcherServlet  當                    handle-
  Request()       個一傳回後畢完理處,求請理處來法方                  org.springframework.
  在現呈要了括包                ,例實的
  web.servlet.ModelAndView                  M odelAndView
  。 息 訊 關 相 的 層 它 其 及 以, 料 資
  View           JSP            的)頁網 如例(層
                                  Model               View

               個一由將求請的者用使,中
                S pring Web MVC            個一第在               H elloController
                             : 示 所 下如作 實 其 , 理 處 來 件 物
      FirstSpringMVC                                 HelloController.java
  package onlyfun.caterpillar;

  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import org.springframework.web.servlet.mvc.Controller;



7 8
Chapter 7 Spring Web MVC            架框

import org.springframework.web.servlet.ModelAndView;

public class HelloController implements Controller {
    private String viewPage;

    public ModelAndView handleRequest(HttpServletRequest req,
                                      HttpServletResponse res)
                                      throws Exception {
        String user = req.getParameter("user");
        return new ModelAndView(viewPage, "user", user);
    }

    public void setViewPage(String viewPage) {
        this.viewPage = viewPage;
    }
}



在定設並,數參求請 的者用使自來了得取,中
           Controller                     個這在   " user"
個一第的
ModelAndView   構 建 ,中 子 例 個 這 在 , 中 例 實 的        ModelAndView
得取來用定設是數引個二第,徑路)源資或(頁網標目的現呈要為數引
   的 料 資 現 呈 層 給 是 數 引 個 三 第 而 , ) (鍵 的 件 物
Model        "     K ey   "                     View                 Model
                                            。件物

        進,求 請 的 者 用 使 集 收 為 用 作 的 件 物 制 控,下 構 架
         Web MVC                                  在
        也,輯邏務商行執中件物制控在應不,作動的關相層 與行
           Web
        件 物 的 層 務 商 讓 會 這,層 務 商 至 入 侵 的 關 相
             Servlet           API              讓應不
        件物
         Servlet API        讓 能 不 如 例,合 耦 生 產     與
                                         HttpServletRequest
                                   。中之件物層務商至定設接直
器容 其在              的
          Spring Web MVC   ,是處好的      S pring     用使
                                                  Controller       IoC
相 成完來 入 注 賴 依 其 用 利 並 , 理 管 以 加 來
                              Bean    的般一 同 如 以 可 , 下 理 管
       定設中案檔 在以可您,說來子例的邊這以,入注的件物關               XML               Controller
的檔義定        下 一 看 來 ,徑路 頁 網 的 料 資 現 呈 要所, 後 之 畢 完 理 處 求 請  Bean


                                                                           7
Spring 2.0    良信林(冊手術技          – http://openhome.cc        )

  依,容內        web.xml     在請,定設的中        WEB-INF     立建下錄目         mvc-config.xml
   :案檔
      FirstSpringMVC                                               mvc-config.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

        <bean id="viewResolver"
              class="org.springframework.web.servlet.
                       → view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>

        <bean name="/hello.do"
              class="onlyfun.caterpillar.HelloController">
            <property name="viewPage" value="hello"/>
        </bean>

  </beans>



   上際實                          個一據根須必
                 DispatcherServlet                  HandlerMapping    定決,件物
  個一哪由求請           Controller       ,理處來D ispatcherServlet   用使設預     org.spring-
  是就也,
  framework.web.servlet.handler.BeanNameUrlHandlerMapping
  一 哪用 使 定 決 , 的 求 請 者 用 使 及 性 屬
        Bean               "name"  的時義定在 據根                  URL
  ,時  Controller      求請,中子例個這在如例,例實       個        /FirstSpringMVC/hello.do
          為    用使要定決,稱名
  DispatcherServlet                據根
                           "hello.do"                        "name"     "hello.do"
     。理處來例實的
      Bean                   由交求請將是就以所,例實 的
                                          HelloController

  由交會              ,後
             Controller           回傳     當
                                ModelAndView           D ispatcherServlet
  個一置設要需您而因,析解關相的層
  ViewResolver                    作來件物
                                View
  用使以所,術技層 為作 以將中例範個這在,例實
  ViewResolver                                JSP        View


7 1
Chapter 7 Spring Web MVC              架框

org.springframework.web.servlet.view.InternalResourceViewResolver                       ,
InternalResourceViewResolver      置設要需        "viewClass"        是設預,    org.spring-
framework.web.servlet.view.InternalResourceView              援支別類個這,
Servlet        。)      、 是像(源資關相的術技
                                  JSP    S ervlet

    與會性屬       、      的
    InternalResourceViewResolver            "prefix"    " suffix"              Model-
則,串字
AndView  為 回 傳 訊資徑 路 若 如 例 , 合 結 訊 資 徑 路 的 回 傳                      "hello"
   。               是 就 徑 路 的 際 實 ,合結 定 設 子 例 的 上 以 與
                                               /WEB-INF/jsp/hello.jsp

       :       的試測個一寫中
                   /WEB-INF/jsp/         在以可後最          hello.jsp


  FirstSpringMVC                                                          hello.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>First Spring MVC</title>
</head>
<body>
    <h1>Hello, ${user}!!</h1>
</body>
</html>



         由經,件物   的置設中
          ModelAndView             在  Model                InternalResourceView-
的取存可中術技 為定設將,析解的
Resolver                       及
             InternalResourceView                             JSP
取來        的中術技 用使以可此因,)
      A ttribute                   (性屬JSP              Expression Language
參 了帶附時     求請在您果如,式程的寫撰所上以依,料資得                        hello.do               " user"
       「的 行執以可,息訊 現出會 的後最則,數
               JSP          " user"                    WTP          R un/Run As/Run
網將請,器覽瀏 動啟並
On Server      動啟動自會 ,令指」
                     W TP                Tomcat              Web
個一,                               向指址
          http://localhost:8080/FirstSpringMVC/hello.do?user=Justin
                   : 示所下 如 面 畫 考 參 的 行 執
                                                                                   7 11
Spring 2.0   良信林(冊手術技          – http://openhome.cc     )




                       圖   7.7 FirstSpringMVC   面畫考參行執

 7.1.3 WebApplicationContext
         的義定 所 己 自 在 要 想 果 如     Servlet   用使中別類    Spring   則,能功器容的
                       用 使以可 也                               例,
              org.springframework.web.context.ContextLoaderListener
 :義定以加籤標
       web.xml用使中            在如
                      <listener>


 ...
 <listener>
     <listener-class>
       org.springframework.web.context.ContextLoaderListener
     </listener-class>
 </listener>
 ...


 取讀會設預 ContextLoaderListener               applicationContext.xml   以可您,
      在要只,檔義定的己自定指              <context-param>    定指中       "contextConfig-
        :如例,數參
 Location"


 ...
 <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/beans-config.xml,
            → /WEB-INF/demo-service.xml</param-value>
 </context-param>
 ...




7 12
Chapter 7 Spring Web MVC         架框

     的義定自在以可著接                Servlet   用使中     org.springframework.web.
context.support.WebApplicationContextUtils       從,            得取中
                                                      ServletContext
org.springframework.web.context.WebApplicationContext           :如例,
WebApplicationContext ctx =
    WebApplicationContextUtils.
        getRequiredWebApplicationContext(
                         this.getServletContext());


     WebApplicationContext        了作實   ApplicationContext      是,面介   Spring
為專     Servlet   的   Web         的計設式程用應ApplicationContext   取在,別類作實
 得WebApplicationContext    得取來它用利以可,後之                Bean   的義定中檔義定
Bean   :如例,例實
Date date = (Date) ctx.getBean("dateBean");


援支不在             Listener   如例(上器容的定設         Servlet 2.2   ,)本版的早更以
  用使以可                                                      來
            org.springframework.web.context.ContextLoaderServlet
 的面上代取       ContextLoaderListener   :如例,定設的
...
<servlet>
    <servlet-name>contextLoader</servlet-name>
    <servlet-class>
      org.springframework.web.context.ContextLoaderServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
...


設假,式方態組的整完範示來例範的單簡個一寫撰,述敘的上以合綜
     : 示 所 下 如 , 能功時 報 供 提 為 用 作 , 式 程
                 Servlet               個一了寫撰您


                                                                         7 13
Spring 2.0   良信林(冊手術技             – http://openhome.cc   )

      WebApplicationContextDemo                           TimeServlet.java
  package onlyfun.caterpillar;

  import    java.io.*;
  import    javax.servlet.*;
  import    javax.servlet.http.*;
  import    org.springframework.web.context.WebApplicationContext;
  import    org.springframework.web.context.
                                     support.WebApplicationContextUtils;

  public class TimeServlet extends HttpServlet {
      public void doGet(HttpServletRequest req,
                      HttpServletResponse res)
                    throws ServletException, IOException {
          WebApplicationContext ctx =
                  WebApplicationContextUtils.
                      getRequiredWebApplicationContext(
                          this.getServletContext());

            PrintWriter out = res.getWriter();
            out.println(ctx.getBean("dateBean"));
        }
  }



   了用使中      個這Servlet                WebApplicationContext   得取試嘗來
 義定中    在以可,
 "dateBean"              web.xml         ContextLoaderListener義定 與
                                                                 Bean
         :如例,置位的檔
      WebApplicationContextDemo                                    web.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    → http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
      <session-config>
          <session-timeout>
              30
          </session-timeout>



7 14
Chapter 7 Spring Web MVC       架框

    </session-config>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/beans-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
         org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>time</servlet-name>
        <servlet-class>
            onlyfun.caterpillar.TimeServlet
        </servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>time</servlet-name>
        <url-pattern>/time.do</url-pattern>
    </servlet-mapping>
</web-app>



了 定 設,中 性 屬
      <context-param>          的             在
                        "contextConfigLocation"                  Bean
          : 示 所 下 如 容 內 的 檔 義 定 ,稱 名 與 置 位 的 檔 義 定
                    B ean


 WebApplicationContextDemo                         beans-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="dateBean"
            class="java.util.Date" scope="singleton"/>

</beans>



                                                                  7 1
Spring 2.0   良信林(冊手術技           – http://openhome.cc        )

 至接 連 器 覽 瀏 用 使 以 可             TimeServlet   執個一,間時的接連示顯會頁網,
     :示所下如面畫的行



                圖   7.8 WebApplicationContextDemo   面畫考參行執的

 7.1.4 Handler Mapping
   ,時到來求請的戶客當                                  決件物
                              D ispatcherServlet         據根
                                                      Handler mapping
 的 應 對至配 分 求 請 將 何 如 , 定          Controller   常通,說來式程用應 於對,
                                                     Web
      至應對徑路 以是就
          URL                Controller   。
 的設預   DispatcherServlet          Handler mapping    是   org.springframework.
 web.servlet.handler.BeanNameUrlHandlerMapping                  在使即以所,  Bean
 告宣確明有沒中檔義定                      BeanNameUrlHandlerMapping   用使會也,
 BeanNameUrlHandlerMapping   依       Bean     的義定   "name"   決來, 之性屬
                                                                  URL
 個一哪用使定         Controller   :如例,
 ...
       <bean id="viewResolver"
             class="org.springframework.web.servlet.
                      → view.InternalResourceViewResolver">
           <property name="prefix" value=”/WEB-INF/jsp/”/>
           <property name="suffix" value=”.jsp”/>
       </bean>

       <bean name="/hello.do"
               class="onlyfun.caterpillar.HelloController">
           <property name="viewPage" value=”hello”/>
       </bean>
 ...


7 16
Chapter 7 Spring Web MVC          架框

 對 者 用 使,中 定 設 的 面 上 在           /hello.do   ,求 請 的 徑 路   D ispatchServlet   都
。理處件物               由交會
         HelloController


      BeanNameUrlHandlerMapping                  的單簡是於用適僅,
                                               Handler mapping
得 使 它為因 , 式 程 用 應 的 型 小        URL      Controller 與 關立 建 接 直 稱 名 別 類 的
         的
         Spring   在,係
                  Handler mapping             是的用使常最中org.springframework.
                                    下如子例的用使個一,
web.servlet.handler.SimpleUrlHandlerMapping
:示所
...
      <bean id="urlHandlerMapping"
            class="org.springframework.web.servlet.
                      → handler.SimpleUrlHandlerMapping">
          <property name="mappings">
              <props>
                  <prop key="/hello.do">helloController</prop>
                  <prop key="/welcome.do">welcomeController</prop>
              </props>
          </property>
      </bean>

      <bean id="viewResolver"
            class="org.springframework.web.servlet.
                     → view.InternalResourceViewResolver">
          <property name="prefix" value=”/WEB-INF/jsp/”/>
          <property name="suffix" value=”.jsp”/>
      </bean>

      <bean id="helloController"
              class="onlyfun.caterpillar.HelloController">
          <property name="viewPage" value=”hello”/>
      </bean>

      <bean id="welcomeController"
            class="onlyfun.caterpillar.WelcomeController">
          ...
      </bean>
...




                                                                         7 17
Spring 2.0   良信林(冊手術技               – http://openhome.cc     )

   的求請是   的  ,中置設的性屬
           "mappings"      在              < prop>     "key"             URL   而,
 的    ,稱名 的求請理處上際實定設間
 <prop>       </prop>    與                          Bean          < prop>    "key"
              :如例,    用使以可還置設
                   Wildcard


 ...
        <bean id="urlHandlerMapping"
              class="org.springframework.web.servlet.
                        → handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/hello*.do">helloController</prop>
                    <prop key="/welcome.do">welcomeController</prop>
                </props>
            </property>
        </bean>
 ....


 以,中置設的面上在                   hello 的尾結 及頭開 .do        URL    給交會都,求請         Bean
       的中檔義定  " helloController"       。理處來
        義定若    Controller   用 使可則 , 範 規 名 命 守 遵 時 稱 名          Spring 2.0   的增新
 org.springframework.web.servlet.mvc.support.ControllerClassName
 HandlerMapping     寫改以可如例,            FirstSpringMVC   的   mvc-config.xml   :下如
 ...
        <bean id="viewResolver"
              class="org.springframework.web.servlet.
                       → view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>

        <bean id=”controllerClassNameHandlerMapping”
             class="org.springframework.web.servlet.mvc.
                       → support.ControllerClassNameHandlerMapping"/>

        <bean name="helloController"
              class="onlyfun.caterpillar.HelloController">


7 18
Chapter 7 Spring Web MVC          架框

          <property name="viewPage" value="hello"/>
      </bean>
...


             與求請的    將動自會
      ControllerClassNameHandlerMapping                 hello*
Controller      尋找試嘗會將求請的    如例,對比稱名別類
                                  hello.do                           Hello-
Controller        則,求請的   是若,的樣同,理處來例實 welcome*                  Controller-
             。理處來例實
ClassNameHandlerMapping   尋找試嘗會        WelcomeController



7.1.5 Handler Interceptor
           在是者或,後前的行執
             Controller   在果如                View   記些 一 作 算 打 後 之 製 繪
                 作實以可,作動等求請截攔或錄org.springframework.web.servlet.Hand-
下如義定其,法方個三了範規中面介個這在,面介
lerInterceptor
                            :示所
package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest request,
                HttpServletResponse response,
                    Object handler) throws Exception;
    void postHandle(HttpServletRequest request,
                HttpServletResponse response,
                Object handler,
                ModelAndView modelAndView) throws Exception;
    void afterCompletion(HttpServletRequest request,
                HttpServletResponse response,
                Object handler,
                Exception ex) throws Exception;
}




                                                                         7 1
Spring 2.0    良信林(冊手術技                – http://openhome.cc    )

        的回傳,行執被前之求請理處
          preHandler()         Controller在會                                  boolean
  回傳果如,求請理處來                是或
                   Handler Interceptor            讓否是定決值
                                                 Controller
  false      ,求請理處不就              或
                          Interceptor         的來下接則,
                                          Controller                p ostHandler()
  在會法方       Controller,行執被後之求請完理處                    在會則
                                                       a fterCompletion()
  View                               。行執被後之成完製繪
                                                承繼以可您
                     o rg.springframework.web.servlet.handler.HandlerInter-
  方的 要 必 對 針 要 只 您,面 介
  ceptorAdapter                        了 作 實 它,
                                  HandlerInterceptor
         作實中當在,案專                     改 修以可 如 例 , 義 定 新 重 法
                                    FirstSpringMVC                          Logging-
  Interceptor  : 錄 記 作來後 、 前 的 理 處 件 物 制 控 被 求 請 在 ,
      HandlerInterceptorDemo                             LoggingInterceptor.java
  package onlyfun.caterpillar;

  import     java.util.logging.Logger;
  import     javax.servlet.http.HttpServletRequest;
  import     javax.servlet.http.HttpServletResponse;
  import     org.springframework.web.servlet.ModelAndView;
  import     org.springframework.web.servlet.
                        handler.HandlerInterceptorAdapter;

  public class LoggingInterceptor
          extends HandlerInterceptorAdapter {
      private Logger logger =
              Logger.getLogger(this.getClass().getName());

          public boolean preHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler) throws Exception {
              logger.info(
                      handler.getClass().getName() + "        ...");
                                                              行執始開
              return true;
          }

          public void postHandle(HttpServletRequest request,
                      HttpServletResponse response, Object handler,




7 2
Chapter 7 Spring Web MVC   架框

                  ModelAndView modelAndView) throws Exception {
          logger.info(
                  handler.getClass().getName() + "    畢完行執...");
      }

      public void afterCompletion(HttpServletRequest request,
                  HttpServletResponse response, Object handler,
                  Exception ex) throws Exception {
          logger.info("畢完理處求請    ...");
      }
}



個一這用使要             HandlerInterceptor   在須必,   Bean   ,義定行進中檔義定
     :如例
    HandlerInterceptorDemo                              mvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

      <bean id="loggingInterceptor"
            class="onlyfun.caterpillar.LoggingInterceptor"/>

      <bean id="viewResolver"
            class="org.springframework.web.servlet.
                     → view.InternalResourceViewResolver">
          <property name="prefix" value="/WEB-INF/jsp/"/>
          <property name="suffix" value=".jsp"/>
      </bean>

      <bean id="urlHandlerMapping"
            class="org.springframework.web.servlet.
                      → handler.SimpleUrlHandlerMapping">
          <property name="interceptors">
              <list>
                  <ref bean="loggingInterceptor"/>
              </list>



                                                                   7 21
Spring 2.0   良信林(冊手術技           – http://openhome.cc       )

           </property>
           <property name="mappings">
               <props>
                   <prop key="/hello.do">helloController</prop>
               </props>
           </property>
       </bean>

       <bean id="helloController"
             class="onlyfun.caterpillar.HelloController">
           <property name="viewPage" value="hello"/>
       </bean>

  </beans>



 當;                     是
                       UrlHandlerMapping 的用使所意注SimpleUrlHandlerMapping
 控 在,錄 記 行 進 會 都 後 前 的理處 被 求 請 在 , 時 求 請
       DispatcherServlet                        過透
        C onsole        :示所下如訊資的到看所)          (台制




                   圖   7.9 HandlerInterceptorDemo   面畫考參行執的


 7.1.6 Controller 繼承架構

 是的求請理處上際實,後之求請出送者用使當                                             實以可您,
                                                          Controller
   ,中   在,求請理處來面介
    Controller        作               Spring        C ontroller   容     是
                                                                   Spring IoC




7 22
Chapter 7 Spring Web MVC        架框

  的富豐供提      Bean。例實 個一的理管器  S pring                 Controller   根以可,構架承繼
的需所 成 完 以 , 別 類 個 某承繼 來 求 需 的 上 際 實 據                      Controller。理處
:構架承繼的       Spring中      出列下以
                           Controller




                       圖   7.10 Spring   中   Controller   構架承繼
   介簡別分下以         Controller    :用作之別類關相
  AbstractController
  AbstractController            了承繼並,面介
                                Controller       了作實              WebContentGene-
   了供提,
  rator                直以可您。理處的)
                 Session              (化步同與取快    s ynchronized
      承繼接              處來法方
          AbstractController           義 定 新 重 並,handleRequestInternal()
  :如例,求請理
  public class SomeController extends AbstractController {
      public ModelAndView handleRequestInternal(
                 HttpServletRequest request,
                 HttpServletResponse response) throws Exception {
          ....
          return new ModelAndView("view", "modelName", model);



                                                                             7 23
Spring 2.0   良信林(冊手術技       – http://openhome.cc       )

         }
         ..
    }


    MultiActionController
    的您,時大增模規式程在,別類              個一寫撰求請個一每為果如
                                Controller
    Controller用 使 接 直 或 承 繼 以 可。加 增 速 迅 會 將 別 類     MultiActionController
    寫撰求請個一每用不而,件物個一同於中集理處求請的關相個數將,別類
                                           。件物制控個一
    BaseCommandController        、
                             A bstractCommandController

    使以可則,理管以加中件物            個一至取擷值數參求請將要需果如
                                     Command
    一是     ,中     在。別 類 子 的 別 類
        BaseCommandController                    用
                                               Spring       C ommand
    至定設並取擷數參求請將責負
        JavaBean   B aseCommandController  ,     個
    流理處的續後了義定則
    Command                            ,中件物
                       A bstractCommandController
    ,         義定來                          承繼會常通,程
                   AbstractCommandController        CommandController
                                           :下如子例個一
    public class SomeCommandController
                        extends AbstractCommandController {
        public SomeCommandController() {
            setCommandClass(YourCommand.class);
        }

         public ModelAndView handle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object command,
                         BindException exception) throws Exception {
             YourCommand your = (YourCommand) command;
             ...
             return new ModelAndView(..);
         }
         ..
    }


    AbstractFormController


7 24
Chapter 7 Spring Web MVC            架框

              ,理處單表於對
                   A bstractFormController   單表及,數參求請理處了義定中
   。程流面頁的行進要所時敗失或功成交提
   SimpleFormController
        承 繼 以 可,理 處 單 表 的 單 簡 於 對    SimpleFormController   定 新 重 以 可,別 類
   理處己自要果如,法方
     doSubmitAction()           義                           新重以可則,
                                                 ModelAndView
               。法方
        onSubmit()            義定
   AbstractWizardFormController
        承繼以可,說來頁網的集收料資成完來面畫單表個數要需於對                                    Abstract-
   來能功)   (靈精的式程用應面桌像以可您,
   WizardFormController                                      W izard
                              。單表作製
個一每,紹介的單簡個作先               的上 以 於 對 邊 這 在
                        Controller                                Controller
    明 說 續繼將 下 以 , 明 說 的 細 詳有會 都 中 節 一 下 在 別 類           Spring Web MVC       的
     API                            。 要主
7.1.7 ModelAndView
所時 面 畫 現 呈 , 中 式 程
    ModelAndView               了表代別類
                                Spring Web MVC
能只次一中法方的式程 於由,件物料資 與件物料資
     Model              View                       用使
                                                 Java
同 您 便 方 ,件 物 個 兩 這 裝 封 是 用 作 的
                     ModelAndView     以 所 ,件 物 個 一 傳 回
       Model     View              。 與           回傳時
被稱名       後之,稱名的ModelAndView括包只是           的單簡最
                                          View                  View
面介
View resolver                    作 實 是 就 也,
                            org.springframework.web.servlet.View
      的單簡最,等             或
                   InternalResourceView  如例,析解例實的
                                             JstlView                   Model-
AndView                           :下如式方構建
ModelAndView(String viewName)




                                                                             7 2
Spring 2.0   良信林(冊手術技           – http://openhome.cc             )

 件物 用使以可則,件物料資                的 需 所時面 畫 現 呈 回 返 要 果 如
                                           Model                              Map
 下 用 使 以 可 ,數 引 的 時 構 建 為 作         構 建 在 後 然 ,料 資 集 收 來
                              ModelAndView
                           :法方構建
                ModelAndView                 的本版個這面
 ModelAndView(String viewName, Map model)


 的現 呈 要 在 以 可 後 之 , ) ( 值 與 ) ( 鍵 定 設 中 件 物
       Map              "     K ey     "    "      V alue   "
 資      個一回傳要您果如,)中頁網 在如例(示顯以加出取中面畫  JSP                                       Model
 :本版               個這面下用使以可則,稱名的
                Model                   定指並件物料                  ModelAndView


 ModelAndView(String viewName, String modelName, Object modelObject)


  由藉                 物料資
             modelName     出取中別類作實的  在以可您, View                            Model
 據根並,件        View   現呈等 、頁網 是能可(示顯以加來術技的用使所                    JSP          P df
  。)術技
 用使可也別類ModelAndView                         View    引的時構建為作來件物的面介
 : 法 方 構 建的用 可 個 三 是 下 以 , 數
 ModelAndView(View view)
 ModelAndView(View view, Map model)
 ModelAndView(View view, String modelName, Object modelObject)


       作實個一      View   是例實的          org.springframework.web.servlet.view.
  成完來式方)
 RedirectView    (發轉用使是設預
                 M odelAndView             ,                    F orward
 )    (向導新重用使會則,話的                     用使,面畫果結的求請
                            RedirectView                                      R edirect
      : 如 例 , 果 結 的 求請現 呈 以 , 置 位 面 畫 果結的 定 指 至 導 重 求 請 將




7 26
7 27
                                           throws Exception {
                                           HttpServletResponse res)
         public ModelAndView handleRequest(HttpServletRequest req,
                                                                             ...
                   "
        :如例, 鍵 個一生產動自會法方"                 ,件物   a ddObject()
                                                       入加            Model
 僅以可您,法方         addObject()
                        了增新             ,中M odelAndView
                                                     在         Spring 2.0
                             Web
       。 址 位 式 程 用 應 的 它 其 至 定 指 以 可 ,頁網 個 一 求 要 新 重 器 覽
 瀏由是向導新重,          WEB-INF
                        是像,錄目藏隱的中式程用應 問訪能不                         Web
 以所,出發器覽瀏由是求請的後向導新重,訊資的向導新重現出會上列址
 位的器覽瀏此因,址位的定指所至接連新重會端戶客,址位求請出發新重
 器覽瀏端戶客求要會式程用應 ,話的)                W eb  (向導新重用使 R edirect
                       Web
   。 址 位 式 程 用 應 的它其 至 定 指 能 不 , 行 進 中 式 程 用 應 在 能 只                Web
 式方發 轉 , 源 資 些 這 得 取 以 可 才 , 理 處 的       與     Controller      DispatcherServlet
 過透須必而,源資些這求請接直法無就者用使此如,下                                                WEB-INF
 到放源 資 的 取 存 管 控 要 些 一 將 以 可 此 因 , 錄 目             WEB-INF
                                             是像,錄目部內
                   Web
 的定 設 所 式 程 用 應 問訪以 可 , 行 進 內 之 式 程 用 應 在 是 發 轉 且 而          Web
 ,址位的發轉被現出會不並上列址網,話的式方)                      (發轉用使    F orward
                                                   。錄目式
 程用應 是   Web     FirstSpringMVC
                           中其,址位的樣這                       MVC/pages/index.htm
 /FirstSpring-
            像須必址位的回傳                getViewPage()
                                       以所, 錄 目 根 的 式 程 用 應
 Web是不而,始開錄目根頁網器服伺從須必定設的                       ,邊這在     v iewPage
           ...
           }
                                 new RedirectView(this.getViewPage()));
               return new ModelAndView(
               ...
           public ModelAndView handleRequest(....) ... {
           ...
 架框    Chapter 7 Spring Web MVC
Spring 2.0      良信林(冊手術技             – http://openhome.cc    )

            User user = new User();
            ...
            ModelAndView modelAndView = new ModelAndView(viewPage);
            modelAndView.addObject(user);
            return modelAndView;
        }
 ...

 動自會則,例實           是的       給定設果如
                        addObject()      onlyfun.caterpillar.User
 入加果如,稱名生產來稱名面介或別類照按說是就也, 為 鍵 生產
        "   "    " user"
 null         。             生發會則,
                      IllegalArgumentException

 由,    定指不以可還
        Spring    2.0   的    ModelAndView                           View
 以可如例,稱名   供提求請據根來
 RequestToViewNameTranslator                               View
                       :寫 撰 下 如 中 檔 定 設 在
        <bean id="viewResolver"
              class="org.springframework.web.servlet.
                       → view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>

        <bean id=”controllerClassNameHandlerMapping”
             class="org.springframework.web.servlet.mvc.
                       → support.ControllerClassNameHandlerMapping"/>

        <bean id="viewNameTranslator"
              class="org.springframework.web.servlet.
                       → view.DefaultRequestToViewNameTranslator"/>

        <bean name="helloController"
              class="onlyfun.caterpillar.HelloController">
            <property name="viewPage" value="hello"/>
        </bean>
 ...

        在   HelloController   化例實中       ModelAndView    定指不若,時      View   例,
 :如
7 28
Chapter 7 Spring Web MVC       架框

...
public ModelAndView handleRequest(HttpServletRequest req,
                                      HttpServletResponse res)
                                      throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        ...
        return modelAndView;
    }
...

求請果如以所,                  了定設於由
                    ControllerClassNameHandlerMapping
     了定設於由,求請理處來
hello.do                 讓會則,
                    HelloController                              RequestTo-
並,時       生產中
ViewNameTranslator  然雖,      handleRequest()           ModelAndView
        了合結(理處來
           View      由會但,   定指有沒
                            hello.jsp                      InternalResource-
ViewResolver    。)定設置後與置前的
7.1.8 View Resolver
   的回傳據根
     DispatcherServlet                 ModelAndView  名   析解來例實       View
。件物    的面畫於現呈理處並,稱          Model            V iew   作實給託委是析解的稱名
org.springframework.web.servlet.ViewResolver            ,例實的面介        View-
Resolver   :下如義定面介
package org.springframework.web.servlet;

import java.util.Locale;

public interface ViewResolver {
    View resolveViewName(String, Locale locale)
                                 throws ServletException;
}


     ViewResolver   是例實個一的                        以可您,
                                      InternalResourceViewResolver
在   viewResolver   與    定設中
                         "prefix"      "suffix"   與置前 的 徑 路 定 設 別 分 , 性 屬

                                                                            7 2
Spring 2.0   良信林(冊手術技          – http://openhome.cc    )

  樣這,字文置後            viewPage   個給接直,稱名別區要主的徑路打只以可就性屬
   :範示的定設
  ...
  <bean id="viewResolver"
        class="org.springframework.web.servlet.
                 → view.InternalResourceViewResolver">
      <property name="prefix" value=”/WEB-INF/jsp/”/>
      <property name="suffix" value=”.jsp”/>
  </bean>
  ...


  的際實,後完析解稱名在
      ViewResolve                              View   轉的件物   與製繪
                                                             Model
             作實給交是理處換                                 ,例實的面介
                       org.springframework.web.servlet.View
  View     :下如義定面介
  package org.springframework.web.servlet;

  import java.util.Map;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

  public interface View {
      void render(Map model, HttpServletRequest request,
              HttpServletResponse response) throws Exception;
  }


      是     的設預             如例
             InternalResourceViewResolver          "viewClass"       Internal-
  關相術技層  的它其為性屬
  ResourceView      定設以可也,       "viewClass"               View
  外另,                   為定設如例,別類
                        org.springframework.web.servlet.view.JstlView
   。術技 的同不用適可,別類作實等
         TilesView       、     有還
                      V elocityView                           View

                         用使以可您
                       org.springframework.web.servlet.view.BeanNameView-
  Resolver              :如例,

7 3
Chapter 7 Spring Web MVC            架框

...
<bean id="viewResolver"
      class="org.springframework.web.servlet.
               → view.BeanNameViewResolver"/>

<bean id="hello"
      class="org.springframework.web.servlet.view.JstlView">
    <property name="url" value=”/WEB-INF/jsp/hello.jsp”/>
</bean>
...


                   的回返             當,中定設的上以在
                         ModelAndView            view   為稱名    "hello"   ,時
         "id"          。
                    " hello"   的     為性屬 找尋去會
                               View Bean

用使以可這,中檔性屬個一至來出立獨義定的
            ViewResolver                     將以可
來
org.springframework.web.servlet.view.ResourceBundleViewResolver
   : 如 例 , 術 技 層 示 表 的 同 不 定 設 的 際 實據根 以 可 是 處 好 , 成 達
                               URL


...
<bean id="viewResolver"
      class="org.springframework.web.servlet.
               → view.ResourceBundleViewResolver">
    <property name="basename" value=”views”/>
</bean>
...


      在                         了定設性屬
       ResourceBundleViewResolver          的
                                       "basename"                  "views"
是也    (稱名
      " views"     "basename"       用使將這,)值設預的            views.properties
的術技層示表定設來           "viewClass"      個一如例, 與
                                     "url"              views.properties   的
:示所下如例範寫撰
hello.class=org.springframework.web.servlet.
                   → view.InternalResourceView
hello.url=/WEB-INF/jsp/hello.jsp

welcome.class=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp


                                                                         7 31
Spring 2.0    良信林(冊手術技           – http://openhome.cc      )

 other.class=org.springframework.web.servlet.view.VelocityView
 other.url=/WEB-INF/vm/other.vm



 找尋會則,      為若稱名 的中例實
                 ModelAndView         的回傳在   view           "hello"
 可您 , 的 定 指 及 例 實
 hello.class     hello.url 的應對到得來     及    ViewClass                  URL
 為置設上           在,        的同不置設區地或家國的同不為以    View       "basename"
 以可,
 "views"是定設系語果如,                取讀會設預示表,
                               views.properties                     en_US
 準它為以可,       是 定 設 系 語 果 如,
            views_en_US.properties      備準它為              zh_TW
     定設域區與置設以可中案檔的應對而,
    views_zh_TW.properties                 備                                Locale
          View                       。 的關相
                                   用使以可也
                       org.springframework.web.servlet.view.XmlViewRe-
 solver                    :示所下如例範的定設個一,
 ...
 <bean id="viewResolver"
       class="org.springframework.web.servlet.view.XmlViewResolver">
     <property name="location" value=”/WEB-INF/demo-views.xml”/>
 </bean>
 ...


  是設預性屬     ,中定設的面上在         " location"                       為定設邊這,
                                                       views.xml
 找尋中       到示表,
 demo-views.xml               demo-views.xml            View   例,義定 的
                                                                   Bean
       :義定麼這中
       demo-views.xml在如
 ...
 <bean id="hello"
       class="org.springframework.web.servlet.view.JstlView">
     <property name="url" value=”/WEB-INF/jsp/hello.jsp”/>
 </bean>
 ...




7 32
Chapter 7 Spring Web MVC           架框

     定設 與 制 機 的 作 運 其          BeanNameViewResolver 的傳回當,的似類是時
為稱名 的中例實
ModelAndView                   view       "hello"   義定 找尋去會則,時      Bean
 。定設 的
     "id"      為 的中
              "hello"    View



7.1.9 Exception Resolver
例個這捉捕想您而,外例了出丟中程過行運在
            JSP              或頁網 果如
                        Servlet
定設如例(外法方定設捉捕的外例關有中頁網 與器容用使了除,外
                         JSP
的素元令指
web.xml         頁網 定設是或,籤標
              <error-page>        的            JSP         "page"
理處 誤 錯 定 設 中 檔 義 定 的
"errorPage"              在以可也,)性屬 DispatcherServlet
用使如例,例實              的       個一定設,頁網
                         ExceptionResolver          Bean
org.springframework.web.servlet.handler.SimpleMappingException-
Resolver    :示所下如子例的定設個一,
...
<bean id="viewResolver"
      class="org.springframework.web.servlet.
             → view.InternalResourceViewResolver">
    <property name="prefix" value=”/WEB-INF/jsp/”/>
    <property name="suffix" value=”.jsp”/>
</bean>

<bean id="exceptionResolver"
      class="org.springframework.web.servlet.
             → handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.sql.SQLException">sqlexception</prop>
            <prop key="java.sql.IOException">ioexception</prop>
        </props>
    </property>
</bean>
...




                                                                           7 33
Spring 2.0     良信林(冊手術技            – http://openhome.cc          )

 使時 生 發 外 例 在 並 , 用應動自會
       DispatcherServlet                   ExceptionResolver
 了生發要只,中定設的面上在如例,息訊誤錯示顯來頁網的定指用
 了生發而,
 SQLException       至接連會就,           /WEB-INF/jsp/sqlexception.jsp
 IOException 。       至接連會就,       /WEB-INF/jsp/ioexception.jsp



 7.2 Controller 實作類別
 需 所 作 製 來 求 需 依 以可 , 別 類 關 相 的 面 介
       Spring                Controller    作實供提
 , 理處求 請 的 頁 網 單 表 、 集收數 參 求 請 的 單 簡 是 論 無 , 件 物
      Controller                                      的
 以可別類的應對有都中        W izard 在,等計設的頁網 )            (靈精是至甚
                                                      Spring
                                                    。用應
 7.2.1 AbstractController
  是別類  org.springframework.web.servlet.mvc.AbstractController
  請的者用使了作實式模
 Controller              用使,作實單簡的面介       Template Method
  請對驗檢、理處的)          (頭標取快對了括包,程流的理處求         C aching header
 )      (化步同與得取的
            G ET         、援支的) 、 (法方求
                     P OST                S ession                      s ynchronized
   。別類         用使 以 可 則 , 理 處 作 題議些 這 對 要 需 果 如 , 等       AbstractController

  行執         被法方
       AbstractController      從 handleRequest()               DispatcherServlet
                              : 示所下 如 程 流 作 工 的 始 開
 1. DispatcherServlet      。法方                 行執
                                 handleRequest()

 2.   援 支 不 法 方 果 如,法 方 求 請 的 援 支 驗 檢 來 定 設 的
           "supportedMethods"                           據根
              ServletException               。         出丟則
 3.   得取試嘗,           用使要需否是求請定決定設的
           "requireSession"                             據根         Session
      Session     。               出丟則
                                 Session       得取有沒果如,
                                                     ServletException




7 34
Chapter 7 Spring Web MVC           架框

4.   據根             (頭標取快定設否是定決定設的
          "cacheSeconds"                                    C aching header。)
5.   叫呼                   據根,法方
          handleRequestInternal()                 "synchronizeOnSession"   是定決
     對否   Session       。)      (化步同行進
                                  s ynchronized


          於對 AbstractController   以可就解了的本基個有要只,程流作工的別類
   承繼 接 直 以 可 , 了     AbstractController  義定新重並,別類              handleRequest-
:如例,法方
Internal()


public class SomeController extends AbstractController {
    protected ModelAndView handleRequestInternal(
               HttpServletRequest request,
               HttpServletResponse response) throws Exception {
        ....
        return new ModelAndView("view", "modelName", model);
    }
    ..
}


方些一的好義定經已作操接直以可,話的別類
             AbstractController         用使
, 式 方 求 請 的 許 允 所 定 設, 法 方          叫呼以可如例,法
                     setSupportedMethods()
      、 、 援 支只則 , 話 的 寫 撰 下 如 若 時 作 實
      Controller                           如例             GET    P OST     H EAD
                                        :求請的
package onlyfun.caterpillar;
...
public class HelloController extends AbstractController {
    ...
    public HelloController() {
        this.setSupportedMethods(
                new String[] {"GET", "POST", "HEAD"});
    }

     protected ModelAndView handleRequestInternal(
                    HttpServletRequest req, HttpServletResponse res)
                                           throws Exception {
         ...
     }
}



                                                                              7 3
Spring 2.0   良信林(冊手術技            – http://openhome.cc         )

       則,話的求請式方的許允不以果如                          Controller   出丟會候時的理處在
 org.springframework.web.servlet.support.RequestMethodNotSupported-
 Exception    。外例的

 7.2.2 MultiActionController 與 ParameterMethodName-
          Resolver
 個一寫撰理處的求請個一每為若,大越來越模規的式程用應果如
 的多越來越有中式程用應
 Controller                到現發您,的快很,別類         Web
 如例,別類個一在織組以可是責職些一的中當上實事而,別類
 Controller
 個一在織組以可就,法方等                、 、 的關相作操庫料資與
                         list()   a dd()   d elete()
                                                     。別類
              :別 類 子 個 一 的 別 類
                    AbstractController         用使以可您            o rg.springframe-
 在您讓以可它。
 work.web.servlet.mvc.multiaction.MultiActionController
 的 中當行 執 來 求 請 的 者 用 使據根 並 , 法 方 個 多 義 定 中 別 類
       Controller                                      個一
                                                 。法方個某
                   個一合配要您,
              MultiActionController              用使要     org.springframework.
         ,例實的
 web.servlet.mvc.multiaction.MethodNameResolver                      M ultiAction-
 Controller       是別類                     的用使設預
                         MethodNameResolver                  org.springframework.
 個 這,
 web.servlet.mvc.multiaction.InternalPathMethodNameResolver
        行執斷判來稱名案檔的求請後最,中址網的給所據根以可別類                                    Controller
                     行執會求請的 /test.do    如例,法方個一哪的中     test (HttpServletRequest,
 HttpServletResponse) 用使會不常通但。法方                       InternalPathMethodName-
 是像,點優些一的
 Resolver                        用使了去失就這為因,
                                       MultiActionController
                      。法 方 的 行 執 要 所 定 決來數 參 求 請 的 者 用 使 依


7 36
Chapter 7 Spring Web MVC        架框

    用使在常通      MultiActionController   配搭會時    org.springframework.
web.servlet.mvc.multiaction.ParameterMethodNameResolver       是或   o rg.
springframework.web.servlet.mvc.multiaction.PropertiesMethodName-
       行執要定決數參以,數參求請個一據根是都別類個兩,
Resolver                                                     Controller
可, 例 為               以 先 邊 這, 法 方 個 一 哪 的 中 別 類
                              ParameterMethodNameResolver
    Bean             :寫撰麼這中檔義定 在以
  MultiActionDemo                                    mvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="urlMapping"
          class="org.springframework.web.servlet.
                     → handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/book.do">bookController</prop>
            </props>
        </property>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.
                    → view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="paraMethodResolver"
          class="org.springframework.web.servlet.mvc.
                    → multiaction.ParameterMethodNameResolver">
        <property name="paramName" value="action"/>
        <property name="defaultMethodName" value="list"/>
    </bean>




                                                                   7 37
Spring 2.0   良信林(冊手術技           – http://openhome.cc   )

       <bean id="bookController"
             class="onlyfun.caterpillar.BookController">
           <property name="methodNameResolver"
                     ref="paraMethodResolver"/>
           <property name="testPage" value="test"/>
       </bean>

  </beans>



 設性屬              用 使 ,中 義 定 的
         " paraMethodResolver"      Bean              在
                                                     "paramName"
 沒中求 請 是 若 , 法 方 的 行執 要 所 定 指 數 參
       HTTP              "action"        用使中求請          在定
 方的定設所性屬 "action"                用使會則,數參              定指有
                                     "defaultMethodName"
                    list()        。法方 是的定設邊這,法
      在義定中當,別類
       BookController                   承繼
                             MultiActionController               "action"
                              : 如 例 , 法 方的行 執 要 所 下 定 指 數 參
   MultiActionDemo                                   BookController.java
  package onlyfun.caterpillar;

  import javax.servlet.http.*;
  import org.springframework.web.servlet.ModelAndView;
  import org.springframework.web.servlet.mvc.
                   multiaction.MultiActionController;



  public class BookController extends MultiActionController {
      private String testPage;

       public ModelAndView list(HttpServletRequest req,
                             HttpServletResponse res) {
           return new ModelAndView(
                           this.getTestPage(),"executed", "list");
       }

       public ModelAndView add(HttpServletRequest req,
                              HttpServletResponse res) {




7 38
Chapter 7 Spring Web MVC       架框

           return new ModelAndView(
                           this.getTestPage(),"executed", "add");
      }

      public ModelAndView delete(HttpServletRequest req,
                               HttpServletResponse res) {
          return new ModelAndView(
                         this.getTestPage(),"executed", "delete");
      }

      public String getTestPage() {
          return testPage;
      }

      public void setTestPage(String testPage) {
          this.testPage = testPage;
      }
}


           與               括包須必,中法方的義定到意注
                                      HttpServletRequest    HttpServlet-
    。本版的
Response            數參 個 三 第 有 帶 用 使 以 可 也 , 數 參 的
                                              HttpSession

試測於用,例範的單簡個一是只別類    BookController         的義定所上以
目示表,串字個一定設是只理處的作所它,作運的
MultiActionController
者 用 使 示 顯 以 用 , 頁 網 的 用 試 測 個 一 計 設 以 可,稱 名 法 方 的 行 執 所 前
                                              JSP
                                       :如 例 , 法 方 的 求 請 所
    MultiActionDemo                                            test.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>MultiAction Test Page</title>
</head>
<body>
    <H1> "${executed}" method is executed.</H1>




                                                                     7 3
Spring 2.0   良信林(冊手術技         – http://openhome.cc        )

  </body>
  </html>



  行執個一,數參求請上附中址網在以可,子例的求請出發個看際實來
                        :示 所 下 如 面 畫 考 參 的




                     圖   7.11 MultiActionDemo   果結行執的案專

  7.2.3 MultiActionController 與
            PropertiesMethodNameResolver
  寫撰是不而,中件物)            (託委個一在織組法方有所將以可也您       d elegate
  , 法方的 定 指 行 執 件 物 個 這給託 委 , 時 到 來 求 請 當 , 中 別 類
      Controller                                          在
  例,件 物 託 委 至 考 參 性 屬         的
               MultiActionController    "delegate"定設要只您
                                      : 下如計 設 以 可 件 物 託 委 如
      MultiActionDemo2                                      BookDelegate.java
  package onlyfun.caterpillar;

  import javax.servlet.http.*;
  import org.springframework.web.servlet.ModelAndView;

  public class BookDelegate {
      private String testPage;

        public ModelAndView list(HttpServletRequest req,
                              HttpServletResponse res) {



7 4
Chapter 7 Spring Web MVC     架框

          return new ModelAndView(
                  this.getTestPage(),"executed", "list");
      }

      public ModelAndView add(HttpServletRequest req,
                             HttpServletResponse res) {
          return new ModelAndView(
                  this.getTestPage(),"executed", "add");
      }

      public ModelAndView delete(HttpServletRequest req,
                               HttpServletResponse res) {
          return new ModelAndView(
                  this.getTestPage(),"executed", "delete");
      }

      public String getTestPage() {
          return testPage;
      }

      public void setTestPage(String testPage) {
          this.testPage = testPage;
      }
}



   承繼用不在現          MultiActionController    義定來別類   Controller   而,別類
義定 接 直 中 檔 義 定 在 是                         :例實的
                       MultiActionController


    MultiActionDemo2                                   mvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

      <bean id="urlMapping"
            class="org.springframework.web.servlet.
                     → handler.SimpleUrlHandlerMapping">
          <property name="mappings">




                                                                   7 41
Spring 2.0   良信林(冊手術技         – http://openhome.cc      )

               <props>
                   <prop key="/book.do">bookController</prop>
               </props>
           </property>
       </bean>

       <bean id="viewResolver"
             class="org.springframework.web.servlet.
                      → view.InternalResourceViewResolver">
           <property name="prefix" value="/WEB-INF/jsp/"/>
           <property name="suffix" value=".jsp"/>
       </bean>

       <bean id="paraMethodResolver"
             class="org.springframework.web.servlet.mvc.
                      → multiaction.ParameterMethodNameResolver">
           <property name="paramName" value="action"/>
           <property name="defaultMethodName" value="list"/>
       </bean>

       <bean id="bookDelegate"
             class="onlyfun.caterpillar.BookDelegate">
            <property name="testPage" value="test"/>
        </bean>

       <bean id="bookController"
             class="org.springframework.web.servlet.mvc.
                      → multiaction.MultiActionController">
           <property name="methodNameResolver"
                     ref="paraMethodResolver"/>
           <property name="delegate" ref="bookDelegate"/>
       </bean>

  </beans>



   用使以可您           MultiActionDemo   這,果結現呈來頁網   的中案專
                                              test.jsp
 與果結行執的式程個             MultiActionDemo 圖考參以可,的同相是案專                 7.11
      。面畫的


7 42
Chapter 7 Spring Web MVC       架框

     用使以可也,式程的面上              PropertiesMethodNameResolver   將如例,
Bean:容內的下以為寫改檔義定
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

   <bean id="urlMapping"
         class="org.springframework.web.servlet.
                   → handler.SimpleUrlHandlerMapping">
       <property name="mappings">
           <props>
               <prop key="/*book.do">bookController</prop>
           </props>
       </property>
   </bean>

   <bean id="viewResolver"
         class="org.springframework.web.servlet.
                  → view.InternalResourceViewResolver">
       <property name="prefix" value=”/WEB-INF/jsp/”/>
       <property name="suffix" value=”.jsp”/>
   </bean>

   <bean id="propMethodResolver"
       class="org.springframework.web.servlet.mvc.
                   → multiaction.PropertiesMethodNameResolver">
       <property name="mappings">
           <props>
               <prop key="/listbook.do">list</prop>
               <prop key="/addbook.do">add</prop>
               <prop key="/deletebook.do">delete</prop>
           </props>
       </property>
   </bean>

   <bean id="bookDelegate"
         class="onlyfun.caterpillar.BookDelegate">
       <property name="testPage" value=”test”/>



                                                                  7 43
Spring 2.0   良信林(冊手術技               – http://openhome.cc       )

       </bean>

     <bean id="bookController"
            class="org.springframework.web.servlet.mvc.
                     → multiaction.MultiActionController">
          <property name="methodNameResolver" ref="propMethodResolver"/>
          <property name="delegate" ref="bookDelegate"/>
     </bean>
 </beans>


          給交會都求請的尾結為         有所,定設的上以據根
                                   book.do                            bookController
 同 依 ,法 方 的       行 執 會 ,時
                      /listbook.do  求 請 而 ,理 處 來bookDelegate        list()
    或 行執來         或           用使別分以可,理道的樣
                                 /addbook.do   /deletebook.do            a dd()   l ist()
                  : 示 所 下 如 面 畫考參 的 行 執 個 一 , 法 方



                 圖   7.12   用使   PropertiesMethodNameResolver   果結行執的

 7.2.4 ParameterizableViewController
 類子的別類                   是別類
       ParameterizableViewController                 AbstractController
 這當,性屬               的它 定 設 , 義 定 中 檔 義 定 在接 直 以 可 , 別
                      Bean                               "viewName"
 , 頁網的 定 指 向 導 接 直 定 設 的
    Controller                     據根會,時行執
                                      "viewName"     個
 個一計設以可如例,求請 頁網 對接直免避來用以可是處好的它用使               JSP
 將以可,制控
 index.jsp                 過透都求請的有所讓了為,         DispatcherServlet
     :義定麼這中檔義定 在接直並,下
 index.jsp            WEB-INF             在置放    Bean




7 44
Chapter 7 Spring Web MVC   架框

...
<beans>
    <bean id="urlMapping"
          class="org.springframework.web.servlet.
                    → handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/index.do">indexController</prop>
               ....
            </props>
        </property>
    </bean>

   <bean id="viewResolver"
         class="org.springframework.web.servlet.
                  → view.InternalResourceViewResolver">
       <property name="prefix" value=”/WEB-INF/jsp/”/>
       <property name="suffix" value=”.jsp”/>
   </bean>

    <bean id="indexController"
          class="org.springframework.web.servlet.
                   → mvc.ParameterizableViewController">
        <property name="viewName" value=”index”/>
    </bean>
<beans>


是求請址網的接連當,定設的上以依                       /index.do   定指所至接連會則,時
   。頁網           的
  /WEB-INF/jsp/index.jsp



7.2.5 AbstractCommandController
數參 求 請 供 提 者 用 使 到 遇 當 ,
         Controller           是或    用使
                        AbstractController
這 將算打 果 如 , 數 參 求 請 得 取 中 件 物    從行自須必,時
                HttpServletRequest
等換轉態型行進或輯邏關相寫撰行自須必,件物個某至定設數參求請些
                                     。作動

                                                                7 4
Spring 2.0      良信林(冊手術技         – http://openhome.cc    )

        承繼以可        org.springframework.web.servlet.mvc.AbstractCom-
 當,件物
 mandController 個一供提並,別類             作實來
                             Controller                   Command
 稱名數 參 求 請 對 比 著 試 會                   ,時到來求請者用使
                     A bstractCommandController
 對叫呼並,)稱名法方
      Command          是就也(稱名法方
                    Setter              的上     setXXX 與
 會 也,態 型 本 基 是 數 參 的 上
        Setter          果如,值數參求請定設法方        Setter  的應
                          。 態 型 的 應 對為值 數 參 求 請 換 轉 動 自
  :別類           為 作 別 類 個 一 了 計 設您設 假 , 說 來 子 例 個 舉
                                            User          Command


      AbstractCommandDemo                                            User.java
  package onlyfun.caterpillar;

  public class User {
      private String name;
      private String password;

        public void setName(String name) {
            this.name = name;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getName() {
            return name;
        }

        public String getPassword() {
            return password;
        }
  }



        了括包中求請 果如        "name"   與   "password"   為 裝封要想數參 些這而,數 參
 User     承 繼則, 例 實  AbstractCommandController     使以可 , 時     作實
                                                        Controller




7 46
Chapter 7 Spring Web MVC      架框

     用
 setCommandClass()   定指 來   Command    的它義定新重並,別類          handle()   方
:如例 ,法
 AbstractCommandDemo                             UserController.java
package onlyfun.caterpillar;

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.
                      mvc.AbstractCommandController;
import org.springframework.validation.BindException;

public class UserController extends AbstractCommandController {
    private String userPage;

    public UserController() {
        setCommandClass(User.class);
    }

    protected ModelAndView handle(HttpServletRequest request,
                        HttpServletResponse response,
                        Object command,
                        BindException exception) throws Exception {
        User user = (User) command;

         Map model = new HashMap();
         model.put("name", user.getName());
         model.put("password", user.getPassword());

         return new ModelAndView(getUserPage(), "userInfo", model);
    }

    public void setUserPage(String userPage) {
        this.userPage = userPage;
    }

    public String getUserPage() {




                                                                  7 47
Spring 2.0   良信林(冊手術技           – http://openhome.cc   )

           return userPage;
       }
  }



 並,例實的     了得取接直,中法方
       UserController       的
                         handle()                    Command
 法方      與       作操接直,後之 為面介作操換轉在
                    User                 getName()      getPassword()
 頁網 在以,訊資集收來件物 個一了用使上以在,數參求請得取來        Map                        JSP
              : 下 如 計 設 頁 網 設假 , 訊 資 些 這 現 呈 中
                           JSP


      AbstractCommandDemo                                     userInfo.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
  <title>AbstractCommandController Demo</title>
  </head>
  <body>
      <h1> :稱名 ${userInfo['name']}</h1>
      <h1> :碼密 ${userInfo['password']}</h1>
  </body>
  </html>



       在以可著接      Bean   的關相定設中檔義定           Bean   :示所下如,訊資
      AbstractCommandDemo                                   mvc-config.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="urlMapping"
             class="org.springframework.web.servlet.
                      → handler.SimpleUrlHandlerMapping">



7 48
Chapter 7 Spring Web MVC     架框

        <property name="mappings">
            <props>
                <prop key="/user.do">userController</prop>
            </props>
        </property>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.
                    → view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="userController"
          class="onlyfun.caterpillar.UserController">
        <property name="userPage" value="userInfo"/>
    </bean>

</beans>



    :數 參 求 請 上 附 列 址 網在接 直 時 求 請 在 , 面 畫果結 的 行 執 個 一 看 看 來




              圖    7.13 AbstractCommandDemo   果結行執的案專

7.2.6 AbstractFormController
                             承繼過透常通,求需單表的單簡於對
                                      org.springframework.web.servlet.
    或          義定新重並,
mvc.SimpleFormController          義定來
                                 Controller             onSubmit()
    定 程流理 處 單 表 的 正 真 上 際實而 , 能 功 單 表 成 完 來 法 方
doSubmitAction()



                                                                     7 4
Spring 2.0    良信林(冊手術技            – http://openhome.cc          )

    ,                              在義
           org.springframework.web.servlet.mvc.AbstractFormController
    :明說的中當下一理整邊這,用作之法方的串連一其明說有,中件文 在
         API

    1.     。例實的             個一傳回要,法方
               formBackingObject()            行執            commandClass

    2.   ,作 動 等 化 式 格 作 的 定 特
               initBinder()       對 您 許 允,法 方 行執
                                            Command              Field
                。定設的      或態型本基非供提,等式格錢金、式格期日如例                String

    3.          。現展的單表於用,件物 個一回返,法方
               showForm()                     行執
                                              View

    4.                 用應則, 為定設被性屬
                "bindOnNewForm"               果如       true              ServletRequest-
         行執且並,件物單表的新個一入填來數參求請始初據根
         DataBinder
         onBindOnNewForm()           。法方
    5. showForm()
         程過的單表現展在果如,法方                  行執會法方
                                     referenceData()
                      :如例,件物 個一傳回以可,料資關相些一要需,中       Map

         protected Map referenceData(
                 HttpServletRequest request) throws Exception {
             Map ref = new HashMap();
             ref.put("defalutUser", "guest");
             return ref;
         }

                 用使中頁網 在以可就,來一樣這
                               JSP                 ${defaultUser}   ,料資現呈來法寫的
                    。   是會值的得取所如例
                               "guest"

    6. Model
         。寫填行進並單表到看以可者用使,現展被件物
          : 行 進 程 流 的下以 依 會 將 , 單 表 出 送後之 單 表 完 寫 填 者 用 使
    1.   式方的樣這   用想不果如,       用使常通,出送單表的者用使受接  POST                     POST
          。法方          義定新重以可,單表出送否是者用使斷判來                 isFormSubmission()

    2.   以法方          行 執 會 則,定 設 有 沒 性 屬
               "sessionForm"                 果如             formBackingObject()
         執則到找有沒果如,件物單表得取中          從試嘗則否,件物單表得取
                                         session




7
Chapter 7 Spring Web MVC         架框

          行
       handleInvalidSubmit()     重並件物單表的新立建 試嘗是作動的設預,法方
     。單表寫填新
3. ServletRequestDataBinder
             。件物單表入填數參求請的前目據根
4.   行 進 件 物 單 表 對 以 可 前 之 料 資 證 驗,後 之 料 資 定 綁 在,法 方
         onBind()                                      行執
                                               。作動改修的訂自些一
5.                  。器證驗用使則,定設被性屬
         "validateOnBinding"                           果如
6.   些 一 作 件 物 單 表 對 後 之 料 資 證 驗 在 您 許 允,法 方
         onBindAndValidate()                           行執
                                                      。理處
7.   要別類子,法方                              行執後最,畢完理處件物單表
                                    processFormSubmission()
                               。求請的者用使成完以,法方個這義定新重

7.2.7 SimpleFormController
                            是
      org.springframework.web.servlet.mvc.SimpleFormController
AbstractFormController      類個這承繼接直以可單表的單簡於對,別類子的
義定新重並,別                     請的者用使理處以法方
                    onSubmit()     doSubmitAction()   或
     ,求
      S impleFormController            :的 樣 這 是 程 流 理 處 的
1.       processFormSubmission()       行執
                                     驗檢以       Errors   時證驗或定綁在看看,件物
                                。誤錯的何任無有
2.            。面頁的定設所        傳回,生發誤錯有果如
                             "formView"

3.   也則, 傳回並義定新重被     據根
         isFormChangeRequest()         果如   request                  true
     讓,       行執會前之
              "formView" 到 回 在,       到回會
                                  "formView"                 onFormChange()
                           。件物單表正修會機有您
4.         、         有帶行執會則,生發誤錯有沒果如          HttpServletRequest    H ttpServlet-
     帶僅行執是設預,
     Response     的數參
                 O bject      、    、
                           B indException             onSubmit()
        有只行執是設預者後而,
     Object              的
                 BindException      及
                                   onSubmit()                               Object



                                                                               7     1
Spring 2.0   良信林(冊手術技           – http://openhome.cc        )

        義 定 新 重 慮 考 以 可,
                onSubmit() 的 定 設 向 導 是 設 預,         的數參
                                                "successView"
                 向導會設預,
        doSubmitAction()          回返用不,    ModelAndView                 "success-
        。用使以可時件物料資
        View"            何任送傳"successView" 向 要 需 不 在,
                                                    Model


    範 示 以 , 式 程入登 單 表 個 一 作 實 下 以                SimpleFormController   ,用作的
                :        個一計設先首
                   form.jsp


      SimpleFormDemo                                                    form.jsp
    <%@ page language="java" contentType="text/html; charset=BIG5"
        pageEncoding="BIG5"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
    <title>Login Form</title>
    </head>
    <body>
        <h1>        </h1>
                 單表入登
           :碼密與稱名者用使入輸請       <p>
        <form name="loginform"
               action="/SimpleFormDemo/login.do" method="POST">
          稱名 <input type="text" name="username"/><br>
          碼密 <input type="password" name="password"/><br>
             <input type="submit" value="   "/>定確
        </form>
          。中面頁個這到回再會誤錯入輸:意注
    </body>
    </html>



      數參個兩遞傳中單表                 "username"       的單表意注,
                                               "password"             與 "method"
     樣這,    為定設性屬"POST"           Spring   看 先。中 件 物 單 表 入 填 數 參 求 請 將 會 才
    :寫撰的        看
        LoginController




7   2
Chapter 7 Spring Web MVC       架框

    SimpleFormDemo                               LoginController.java
package onlyfun.caterpillar;

import org.springframework.web.servlet.
                          mvc.SimpleFormController;
import org.springframework.web.servlet.*;

public class LoginController extends SimpleFormController {
    public LoginController() {
        setCommandClass(LoginForm.class);
    }

     protected ModelAndView onSubmit(
                 Object command) throws Exception {
        LoginForm form = (LoginForm) command;

         if("caterpillar".equals(form.getUsername()) &&
            "123456".equals(form.getPassword())) {
            return new ModelAndView(
                    getSuccessView(),"user", form.getUsername());
         }
         else {
             return new ModelAndView(getFormView());
         }
     }
}



,件物單表了表代件物個這,件物
     onSumit()                 收接法方
                           command
的義定中
getSuccessView() 是              與
                      getFormView()     SimpleFormController
   在接直以可會待,頁網標目的敗失與證驗過通示表別分,法方個兩                                    Bean
    :    的 單 簡個是 只 它 , 件 物 單 表 看看來 先 , 義 定 中 檔 義 定 JavaBean


    SimpleFormDemo                                     LoginForm.java
package onlyfun.caterpillar;

public class LoginForm {




                                                                     7     3
Spring 2.0   良信林(冊手術技          – http://openhome.cc   )

         private String username;
         private String password;

         public void setUsername(String username) {
            this.username = username;
         }

         public void setPassword(String password) {
             this.password = password;
         }

         public String getUsername() {
            return username;
         }

         public String getPassword() {
            return password;
         }
    }



         看看來下接     Bean   :的寫撰何如是檔義定
        SimpleFormDemo                                        mvc-config.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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

         <bean id="urlMapping"
               class="org.springframework.web.servlet.
                       →   handler.SimpleUrlHandlerMapping">
             <property name="mappings">
                 <props>
                     <prop key="/login.do">loginController</prop>
                 </props>
             </property>
         </bean>

         <bean id="viewResolver"



7   4
Chapter 7 Spring Web MVC       架框

          class="org.springframework.web.servlet.
                   →  view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="loginController"
          class="onlyfun.caterpillar.LoginController">
        <property name="successView" value="success"/>
        <property name="formView" value="form"/>
    </bean>

</beans>



 了義定中檔義定           "successView"       與
                                      "formView"   中其,   form.jsp   已前之
下一 看 來 , 成 完 寫 撰 經     success.jsp   :寫撰的
 SimpleFormDemo                                             success.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Login Success</title>
</head>
<body>
    <H1> !囉哈  ${user}   </H1>
                       !!
     !物禮秘神的您是這      ^o^
</body>
</html>



  求請接直      login.do   入登 單 表 傳 回 會 以 所 ,查檢 入 登 過 通 未 於 由 , 話 的
:示所下如,面畫


                                                                      7
Spring 2.0   良信林(冊手術技          – http://openhome.cc    )




                        圖   7.14 SimpleFormDemo   單表入登的案專
    的 敗 失 入 登,稱 名 的 者 用 使 示 顯 並 入 進 會,話 的 功 成 入 登
                                 success.jsp
    如面畫的功成入登,單表入登的來原到回會,定設的
             "formView"                        依,話
                                             :示所下




                    圖     7.15 SimpleFormDemo   面畫功成入登的案專

    7.2.8 AbstractWizardFormController
         org.springframework.web.servlet.mvc.AbstractWizardFormCont-
    卷問於用常通,)
    roller     (靈精的式程用應面桌如出計設您讓以可                   W izard
    卷問將如不,容內卷問的有所現呈單表個一用使其與,時長當相容內單表
        承繼以可您,卷問成完頁一頁一者用使讓,面畫個數作分容內                            Abstract-
    是的義定中當,法方       義定新重並,
    WizardFormController                 processFinish()
                      : 如 例 ,理處 的 後 交 提 卷 問 部 全


7   6
Chapter 7 Spring Web MVC       架框

    AbstractWizardDemo                            WizardController.java
package onlyfun.caterpillar;

import java.util.*;
import javax.servlet.http.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.
                    mvc.AbstractWizardFormController;
import org.springframework.validation.BindException;

public class WizardController
                extends AbstractWizardFormController {
    private String successView;

      public WizardController() {
          setCommandClass(Questionnaire.class);
      }

      protected ModelAndView processFinish(
                            HttpServletRequest request,
                            HttpServletResponse response,
                            Object command,
                           BindException exception) throws Exception {
          Questionnaire questionnaire = (Questionnaire) command;

          Map model = new   HashMap();
          model.put("q1",   questionnaire.getQuestion1());
          model.put("q2",   questionnaire.getQuestion2());
          model.put("q3",   questionnaire.getQuestion3());

          return new ModelAndView(getSuccessView(), "ans", model);
      }

      public void setSuccessView(String successView) {
          this.successView = successView;
      }

      public String getSuccessView() {
          return successView;
      }
}




                                                                     7    7
Spring 2.0   良信林(冊手術技        – http://openhome.cc      )

      個 一在集 收 果 結 卷 問 的 有 所         Command       結將 是 只 式 程 的 面 上 , 中 件 物
    在以,中件物       在定設並得取果
                     Model                 View   別類的          ,料資現呈上
                                                            C ommand
                     :下如計設
        AbstractWizardDemo                               Questionnaire.java
    package onlyfun.caterpillar;

    public class Questionnaire {
        private String question1;
        private String question2;
        private String question3;

          public void setQuestion1(String question1) {
              this.question1 = question1;
          }

          public void setQuestion2(String question2) {
              this.question2 = question2;
          }

          public void setQuestion3(String question3) {
              this.question3 = question3;
          }

          public String getQuestion1() {
              return question1;
          }

          public String getQuestion2() {
              return question2;
          }

          public String getQuestion3() {
              return question3;
          }
    }




7   8
Chapter 7 Spring Web MVC       架框

    定 設 由 藉,中 檔 義 定 在 範 規 是 程 流 的 卷 問
                        Bean                      AbstractWizardForm-
Controller :如例,定決來性屬
             "pages"          的
  AbstractWizardDemo                                  mvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

     <bean id="urlMapping"
           class="org.springframework.web.servlet.
                    →  handler.SimpleUrlHandlerMapping">
         <property name="mappings">
             <props>
                 <prop key="/wizard.do">wizardController</prop>
             </props>
         </property>
     </bean>

     <bean id="viewResolver"
           class="org.springframework.web.servlet.
                    →  view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/jsp/"/>
         <property name="suffix" value=".jsp"/>
     </bean>

    <bean id="wizardController"
           class="onlyfun.caterpillar.WizardController">
         <property name="successView" value="success"/>
         <property name="pages">
             <list>
                 <value>start</value>
                 <value>question1</value>
                 <value>question2</value>
                 <value>question3</value>
             </list>
         </property>
     </bean>

</beans>




                                                                   7
Spring 2.0   良信林(冊手術技          – http://openhome.cc     )

       、     、   依將卷問,定設的上以依                                           、
                                 start.jsp q uestion1.jsp q uestion2.jsp q ues-
        :寫撰的
  tion3.jsp    看看先首,成完來序順的             start.jsp


      AbstractWizardDemo                                            start.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
  <title>Insert title here</title>
  </head>
  <body>
      <form name="questionform"
            action="/AbstractWizardDemo/wizard.do" method="POST">
               !卷問寫填您迎歡
          <input type="submit" value="Start" name="_target1"/>
      </form>
  </body>
  </html>



  網 的 置 位 引 索 中 檔 定設得 取 會 設 預 , 時 器 制 控
                       Wizard                   至接連您當              0
  之面頁的示展要個一下定決,面頁明說卷問或迎歡是常通面頁個一第,頁
  , 數參求 請 的 碼 號 個 一 著 跟 並 , 頭 開        個 一無有 中 求 請 於 在 , 法 方
                                "_target"
  的面上,序順的
        "_target1"  中 檔定設 在 示 表 碼 號 , 定 設 的 樣 這          如例
                                                       <list>
               Start   :面 頁 個 二 第 示 顯 會 , 後 鈕 按 下 按 在 頁 網
      AbstractWizardDemo                                        question1.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
  <title>Question 1</title>




7 6
Chapter 7 Spring Web MVC          架框

</head>
<body>
    <form name="questionform1"
          action="/AbstractWizardDemo/wizard.do" method="POST">
        一題問   <input type="text" name="question1"/><br>
        <input type="submit" value="Previous" name="_target0"/>
        <input type="submit" value="Next" name="_target2"/>
    </form>
</body>
</html>



設預所法方 "_target"      是面頁的示顯定決來碼號與                   依
                                          getTaretPage()
數參個一哪由面頁個一下定決以法方個這義定新重以可也,話的要必,的
的 卷 問 回 返 會,話 的 鈕 按
        question1.jsp     下 按,中 計 設 的
                                    Previous      在,定 決
設的           ,頁一下的卷問回返會,話的鈕按的 下按,頁一上
             Next                                  q uestion2.jsp
案專                  中 碟 光 看 觀 行 自 請 , 幅篇省 節 為 , 似 類 是 也 計
                                           AbstractWizardDemo
  question2.jsp                        。案檔              的
,        數參求請有否是中求請驗檢於在,式方的卷問成完否是定決                        "_finish"
最是            ,法方                 行 執 會就, 值 個 這 到 查 檢 果 如
                            processFinish()        q uestion3.jsp
                          : 的 寫 撰 何 如 是它看 看 來 , 卷 問 個 一 後
 AbstractWizardDemo                                   question3.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Question 3</title>
</head>
<body>
    <form name="questionform3"
          action="/AbstractWizardDemo/wizard.do" method="POST">
        三題問   <input type="text" name="question3"/><br>
        <input type="submit" value="Previous" name="_target2"/>



                                                                    7 61
Spring 2.0    良信林(冊手術技         – http://openhome.cc    )

          <input type="submit" value="Finish" name="_finish"/>
      </form>
  </body>
  </html>



       個一有帶要卷問的出送個一後最得記                               行執會才,數參
                                                "_finish"
            的
 AbstractWizardFormControlle        processFinish()   個一計設後最,法方
 success.jsp   :果結示顯來
   AbstractWizardDemo                                       success.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
  <title>Success</title>
  </head>
  <body>
      <H1>Q1: ${ans.q1}</H1> <br>
      <H1>Q2: ${ans.q2}</H1> <br>
      <H1>Q3: ${ans.q3}</H1> <br>
  </body>
  </html>



       : 示 所 下 如 面 畫果結 的 後 交 提 卷 問 個 一




                 圖   7.16 AbstractWizardDemo   面畫果結交提的案專

7 62
Chapter 7 Spring Web MVC       架框

       個一計設中卷問在以可也您                    Cancel   出送,後鈕按該下按在,鈕按
"_cancel":如例,數參求請
....
       <form name="questionform3"
             action="/AbstractWizard/wizard.do" method="POST">
           ....
           <input type="submit" value="Cancel" name="_cancel"/>
       </form>
....


              行執會則,時數參求請
                     "_cancel"          有帶中求請當          processCancel()   方
:面頁 的 時 始 開 卷 問 回 送者用 使 將 如 例 , 法 方 個這義 定 新 重 以 可 您 , 法
...
       protected ModelAndView processCancel(
                      HttpServletRequest request,
                      HttpServletResponse response,
                      Object command,
                      BindException exception) throws Exception {
           return new ModelAndView("start");
       }
...



7.2.9 ThrowawayController
       org.springframework.web.servlet.mvc.throwaway.ThrowawayCon-
,義定面介的立獨個一是而,中構架承繼
troller         Spring的   在不並
                          Controller
      ,用使複重並生產式方的例單以是不別類的面介該作實                                  T hrowaway-
使複重會不,丟就了用且,件物的新生產要都時求請次一每在
Controller
的供提          (因原的     有帶上稱名是也這,用
                         " Throwaway"            T hrowawayController
               。)件物
          Webwork    的式形     似類是
                          Action




                                                                        7 63
Spring 2.0    良信林(冊手術技         – http://openhome.cc   )

       ThrowawayController   :下如義定的面介
 package org.springframework.web.servlet.mvc.throwaway;

 import org.springframework.web.servlet.ModelAndView;

 public interface ThrowawayController {
     ModelAndView execute() throws Exception;
 }


           作實須必別類的面介
              ThrowawayController         作實          execute()   可,法方
             得使這,數參的何任帶不中法方
          execute()                         到看以                   易
                                                 ThrowawayController
       、          有須必  Controller像要需不,試測於
                                        HttpServletRequest   H ttpServlet-
 Response                        。例實的
 ,話的數參求請集收要果如,數參的何任有沒上法方
       execute()
      悉熟點這(用作的
 ThrowawayController  具兼也身本         Command                       Webwork
    :           個 一 作 實 下 如 以 可如例 , ) 生 陌 不 並 人 的
                                          ThrowawayController


 ....
 public class SomeController implements ThrowawayController {
      private String someParam;

       public ModelAndView execute() throws Exception {
            ....
            return new ModelAndView(...);
       }

       public void setSomeParam(String someParam) {
            this.someParam = someParam;
       }

       ....
 }




7 64
Chapter 7 Spring Web MVC        架框

      至定設之將會,時數參的                 有帶中數參求請當
                            "someParam"                                Throwa-
wayController       。中法方           的應對
                          setSomeParam()

將須必           Bean     ,是的意注須必中檔義定     定設在      T hrowawayController
用 ,例實 的 新 個 一 生 產 要 求 請 的 次 一 每 ,
"scope"               "singleton"  為定設性屬
                                     :如例,丟即過
...
      <bean id="someController"
            class="onlyfun.caterpillar.SomeController"
            scope="singleton">
          ....
      </bean>
...


      DispatcherServlet                        用使會設預
                                         org.springframework.web.servlet.mvc.
                           的下系體承 繼
SimpleControllerHandlerAdapter              得使這,
                                            Controller               Controller
為接直以可都別類                      訴 告 要 了 為 但 ,用 使
                     DispatcherServlet                          DispatchServlet
      用使
      ThrowawayController :如例,告宣中檔義定 在須必,Bean


...
<bean id="throwawayHandler"
      class="org.springframework.web.servlet.mvc.
            → throwaway.ThrowawayControllerHandlerAdapter"/>

      <bean id="simpleHandler"
            class="org.springframework.web.servlet.
              → mvc.SimpleControllerHandlerAdapter"/>
...


  用使以可        ,中定設的面上在    D ispatcherServlet             ThrowawayController   ,
入加再則,系體承繼的面介      合混要您果如
                Controller                                    SimpleController-
。用使合混以可就    種兩此如,
HandlerAdapter                 Handler




                                                                            7 6
Spring 2.0   良信林(冊手術技          – http://openhome.cc         )

 7.3 搭配 Controller 的相關類別
 )
 、   ( 證驗 用使 配 搭 上
      器            在何如紹介將,中節小個這在    Controller                       Validator
 作實來 的     用使何如及以,換轉態型的料資
            Command           作實何如                         Spring    API
                           。能功傳上案檔

 7.3.1 實作 Validator

                  個 一 配 搭 以 可,時
            SimpleFormController                   用使     org.springframework.
 工證驗料資端服伺的本基作您助幫,件物作實的面介
 validation.Validator
 單表 行 進 要 需 給 入 注 為 作 之 將 ,Validator   的用通 個 一 計 設 以 可 , 作
                                                   Bean
              Bean                      。件物 它其的證驗
         : 示 所 下 如義定 其 , 法 方 的 作 實 須 必 個 兩 有 面 介
       Validator


 package org.springframework.validation;

 public interface Validator {
     boolean supports(Class clazz);
     void validate(Object obj, Errors errors);
 }


 件物 的 入 傳 所 對 援 支 否 是 示 表 , 值
       supports()                    個一傳回法方
                                 boolean
 證驗行進法方              用 使 會 才 , 下 況 情 的 回傳 在 有 只 , 證 驗 行 進
                         true                        validate()
 它對以 可 您,件 物 單 表 的 入 傳 示 表 ,中 數 參 的 法 方
            validate()                 o bj           在,作 工
      或          的        用 使 以 可 , 話 的 誤 錯有果 如 , 證 驗 些 一 行 進
                                                 Errors      reject()      reject-
 錯括包中件物
 Value()          若 , 中理處 的 續 後 在 , 息 訊 誤 錯 入 加 法 方 等       errors
                     。面頁的定設所
                    getViewPage()               到回會,息訊誤


7 66
Chapter 7 Spring Web MVC          架框

    :作 實 的 單 簡 個 一 看 來
package onlyfun.caterpillar;

import org.springframework.validation.Validator;
import org.springframework.validation.Errors;

public class LoginValidator implements Validator {
    public boolean supports(Class clazz) {
        return clazz.equals(LoginForm.class);
    }

    public void validate(Object obj, Errors errors) {
        LoginForm form = (LoginForm) obj;

        if(form.getPassword().length() < 4 ) {
            errors.rejectValue("password",
                 "less-than-four", null, "  元字個四於小得不碼密      ");
        }
    }
}



使來案專             的紹介 配搭以可別類
         Validator              7.2.7         個這
                                              SimpleFormDemo
格的碼密查檢是像,件條等性全安、性備完的料資查檢在是常通證驗,用
處的      是 該 應 這 ,確正 否 是 碼 密 與 稱 名 者用使 於 至 , 例 一 是 就 式    Controller
                                              。作工理
中檔義定 在要只,            用使來
         SimpleFormController                 配搭
                                        Validator        Bean
,可即它到考參
    Validator   Bean     讓及以,義定 的                 入加
                                  SimpleFormController
                                                :如例
...
<bean id="loginValidator"
       class="onlyfun.caterpillar.LoginValidator"/>

<bean id="loginAction"
       class="onlyfun.caterpillar.LoginAction">
    <property name="commandClass"


                                                                      7 67
Spring 2.0   良信林(冊手術技           – http://openhome.cc    )

         value=”onlyfun.caterpillar.LoginForm”/>
     <property name="validator" ref="loginValidator"/>
     <property name="successView" value=”success”/>
     <property name="formView" value=”form”/>
 </bean>
 ...


       "validator"            至考參性屬
                               loginValidator   定設有要只,例實      "validator"   ,
 SimpleFormController    。它用使會就
                           用 使 以 可 您,時 證 驗 行 進 在
                                    org.springframework.validation.Valida-
        、
 tionUtils          是像,法方態靜的便方些一有面上,              rejectIfEmpty()   r ejectIf-
         。用使何如看件文 上線查查以可,等
 EmptyOrWhitespace()                        API

       義定 新 重 以 可 ,                 於對 , 面 方 一 另
                          AbstractWizardFormController                  vali-
 datePage()             :如例,證驗行進來法方
 ...
       protected void validatePage(Object command,
                                    Errors errors, int page) {
           (YourCommand) your = (YourCommand) command;
           switch(page) {
                case 1:
                      validator.validateSome(your, errors);
                    break;
                case 2:
                      validator.validateOther(your, errors);
                    break;
                 ....
           }
       }
 ...


 頁一行進每               Wizard的出送次該對針您讓,次一法方該叫呼會都,單表
 ,證驗行進據數             " page"     與,數頁的單表出送次該示表數參              SimpleForm-
   的
 Controller    Validator   動自會不             ,是的同不
                                    A bstractWizardFormController




7 68
Chapter 7 Spring Web MVC     架框

方的應 對 行 進 料 資 的 面 頁 次 當 據 根 要 您 , 法 方
      Validator    validate()         的 行執
。行執來件物            個一由交證驗將,件物託委的上如取採常通,證驗法      Validator



7.3.2 使用 PropertyEditor

           的它,說來別類子其及
             BaseCommandController         於對           Command   件物
    作實個一寫撰以可您 ,態型               是或態型本基受接要定一不並
                                String                            java.
轉 串字的 到 收 接 將 如 例 ,換轉行 進 中 當 在 ,別 類 的
beans.PropertyEditor
      User                           。例實的別類 為換
                :計設下如件物    Command  設假,說來例實個舉
    PropertyEditorDemo                                  SomeForm.java
package onlyfun.caterpillar;

public class SomeForm {
    private User user;

      public void setUser(User user) {
          this.user = user;
      }

      public User getUser() {
          return user;
      }
}



     SomeForm     的現出中其而,表代件物的單表頁網為              User   :計設下如別類
    PropertyEditorDemo                                      User.java
package onlyfun.caterpillar;

public class User {
    private String firstName;



                                                                    7 6
Spring 2.0   良信林(冊手術技         – http://openhome.cc    )

        private String lastName;

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }
  }



  收接   從而然,例實 的態型訂自個一收接將件物
       Command                               User              HTTP
  轉做別類        個一 寫 撰 以 可 您 , 態 型
                 String            是值數參的到      UserPropertyEditor
  義定新重並                         承繼接直常通,換
                          java.beans.PropertyEditorSupport
  getAsText()  :如例,法方
                  setAsText()     及
      PropertyEditorDemo                         UserPropertyEditor.java
  package onlyfun.caterpillar;

  import java.beans.PropertyEditorSupport;

  public class UserPropertyEditor extends PropertyEditorSupport {
      public String getAsText() {
          Object o = this.getValue();

           if(o == null || !(o instanceof User)) {
               return null;
           }

           User user = (User) o;
           String name = user.getFirstName()




7 7
Chapter 7 Spring Web MVC    架框

                            + "," + user.getLastName();
          return name;
      }

      public void setAsText(String text) {
          String[] tokens = text.split(",");

          User user = new User();
          user.setFirstName(tokens[0]);
          user.setLastName(tokens[1]);

          setValue(user);
      }
}



行執會,時串字為換轉件物的定指從須必當                                          接而,法方
                                                   getAsText()
 行執會,時件物的定指為換轉之將要數參到收                          setAsText()   撰來著接,法方
         :     的試測個一寫
              Controller


    PropertyEditorDemo                          SomeFormController.java
package onlyfun.caterpillar;

import org.springframework.web.servlet.
                        mvc.SimpleFormController;
import org.springframework.web.servlet.*;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.
                        bind.ServletRequestDataBinder;

public class SomeFormController extends SimpleFormController {
    public SomeFormController() {
        setCommandClass(SomeForm.class);
    }

      protected ModelAndView onSubmit(
                        Object command) throws Exception {
         SomeForm form = (SomeForm) command;




                                                                   7 71
Spring 2.0   良信林(冊手術技          – http://openhome.cc    )

            Map model = new HashMap();
            model.put("firstName",
                      form.getUser().getFirstName());
            model.put("lastName",
                      form.getUser().getLastName());

            return new ModelAndView(this.getSuccessView(), model);
        }

        protected void initBinder(HttpServletRequest request,
                              ServletRequestDataBinder binder)
                                               throws Exception {
            super.initBinder(request, binder);
            binder.registerCustomEditor(
                    User.class, new UserPropertyEditor());
        }
  }



        了義定新重邊這到意注              initBinder()   用使中當在並,法方             Servlet-
           的
 RequestDataBinder        registerCustomEditor()的訂自冊註法方           Property-
 Editor:容內的檔義定看看來,
      PropertyEditorDemo                                    mvc-config.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

        <bean id="urlMapping"
              class="org.springframework.web.servlet.
                     → handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/index.do">indexController</prop>
                    <prop key="/someForm.do">someFormController</prop>
                </props>
            </property>
        </bean>




7 72
Chapter 7 Spring Web MVC      架框

    <bean id="viewResolver"
          class="org.springframework.web.servlet.
                 → view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="indexController"
            class="org.springframework.web.servlet.
                       →   mvc.ParameterizableViewController">
        <property name="viewName" value="index"/>
    </bean>

    <bean id="someFormController"
          class="onlyfun.caterpillar.SomeFormController">
        <property name="successView" value="hello"/>
    </bean>

</beans>



   : 頁 網 試測個 一 有 寫 撰 設 假 在 現
 PropertyEditorDemo                                         index.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Form</title>
</head>
<body>
    <form name="someForm"
          action="/PropertyEditorDemo/someForm.do" method="POST">
           者用使<input type="text" name="user"/><br>
        <input type="submit" value="Submit"/>
    </form>
</body>
</html>




                                                                 7 73
Spring 2.0   良信林(冊手術技            – http://openhome.cc   )

 由經會,後出送料資當,數參 了定設中位欄入輸在    " user"                          P ropertyEditor
   :寫撰下如頁網    的 果 結理處 現 呈 設 假 , 換 轉 的
                                    hello.jsp


     PropertyEditorDemo                                            hello.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
  <title>User Info</title>
  </head>
  <body>
      <h1>${firstName} - ${lastName}</h1>
  </body>
  </html>



       在果如    index.jsp   入填   "Justin,Lin"   :容內的下以示顯會果結則,



                    圖   7.17 PropertyEditorDemo   面畫果結的案專

 7.3.3 檔案上傳

       作實用使以可則,作動的傳上案檔行進要想果如                             org.springframe-
       ,別類的面介
 work.web.multipart.MultipartResolver                    S pring   供提   org.
 springframework.web.multipart.commons.CommonsMultipartResolver     與
 org.springframework.web.multipart.cos.CosMultipartResolver         支別分,
 援   Commands FileUpload        及   COS FileUpload   。

7 74
Chapter 7 Spring Web MVC       架框

     個 一 了 計 設 您設假 , 子 例 的 際 實 個 舉         FileForm   :別類
    FileUploadDemo                                          FileForm.java
package onlyfun.caterpillar;

public class FileForm {
    private String name;
    private byte[] contents;

      public void setName(String name) {
          this.name = name;
      }

      public void setContents(byte[] contents) {
          this.contents = contents;
      }

      public String getName() {
          return name;
      }

      public byte[] getContents() {
          return contents;
      }
}



     FileForm   是態型性屬的傳上案檔受接中                byte   案檔的傳上者用使,列陣
由藉以可         org.springframework.web.multipart.support.ByteArrayMulti-
partFileEditor為換轉        byte   給定設並列陣         FileForm   義定在須必這,
Controller   :如例,冊註時




                                                                      7 7
Spring 2.0   良信林(冊手術技        – http://openhome.cc   )

   FileUploadDemo                                UploadController.java
  package onlyfun.caterpillar;

  import java.io.BufferedOutputStream;
  import java.io.FileOutputStream;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import org.springframework.validation.BindException;
  import org.springframework.web.bind.ServletRequestDataBinder;
  import org.springframework.web.multipart.
                         support.ByteArrayMultipartFileEditor;
  import org.springframework.web.servlet.ModelAndView;
  import org.springframework.web.servlet.
                                     mvc.SimpleFormController;

  public class UploadController extends SimpleFormController {
      private String path;

       public UploadController() {
           setCommandClass(FileForm.class);
       }

       protected ModelAndView onSubmit(
                               HttpServletRequest request,
                               HttpServletResponse response,
                               Object command,
                               BindException errors)
                                           throws Exception {
           FileForm form = (FileForm) command;

           String storedPath = path +
                               System.getProperty("file.separator") +
                               form.getName();

           BufferedOutputStream bufferedOutputStream =
                   new BufferedOutputStream(
                          new FileOutputStream(storedPath));

           bufferedOutputStream.write(form.getContents());
           bufferedOutputStream.close();




7 76
Chapter 7 Spring Web MVC       架框

          return new ModelAndView(getSuccessView(),
                                  "filename", form.getName());
      }

      protected void initBinder(HttpServletRequest request,
                            ServletRequestDataBinder binder)
                                              throws Exception {
          super.initBinder(request, binder);
          binder.registerCustomEditor(
                  byte[].class, new ByteArrayMultipartFileEditor());
      }

      public void setPath(String path) {
          this.path = path;
      }
}



的傳上案檔用使要,下錄目的定指在存儲會後傳上案檔,定設的上以依
   用使擇選以可,義 定的       入加中 檔義定在須 必,能功
                           MultipartResolver                       Com-
     用使下以如 例,
monsMultipartResolver 或  CosMultipartResolver                Commons-
MultipartResolver    :義定 來
    FileUploadDemo                                     mvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

      <bean id="urlMapping"
            class="org.springframework.web.servlet.
                     →  handler.SimpleUrlHandlerMapping">
          <property name="mappings">
              <props>
                  <prop key="/index.do">indexController</prop>
                  <prop key="/upload.do">uploadController</prop>
              </props>



                                                                    7 77
Spring 2.0   良信林(冊手術技         – http://openhome.cc      )

           </property>
       </bean>

       <bean id="viewResolver"
             class="org.springframework.web.servlet.
                         view.InternalResourceViewResolver">
                         →
           <property name="prefix" value="/WEB-INF/jsp/"/>
           <property name="suffix" value=".jsp"/>
       </bean>

       <bean id="indexController"
               class="org.springframework.web.servlet.
                         →mvc.ParameterizableViewController">
           <property name="viewName" value="index"/>
       </bean>

       <bean id="multipartResolver"
             class="org.springframework.web.multipart.
                         commons.CommonsMultipartResolver">
                         →
           <property name="maxUploadSize" value="1000000"/>
       </bean>

       <bean id="uploadController"
             class="onlyfun.caterpillar.UploadController">
           <property name="formView" value="form"/>
           <property name="successView" value="success"/>
           <property name="path" value="c:upload"/>
       </bean>

  </beans>



 定設由藉,中檔義定在                               為 性屬
                             UploadController   的
                                                "path"        "C:upload"   ,
 在 存儲會 案 檔 的 後 傳 上 示 表       C:upload   個一計設著接,中之錄目            index.jsp   :
   FileUploadDemo                                               index.jsp
  <%@ page language="java" contentType="text/html; charset=BIG5"
      pageEncoding="BIG5"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>



7 78
Chapter 7 Spring Web MVC            架框

<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Upload Page</title>
</head>
<body>
    <form name="uploadForm" enctype="multipart/form-data"
          action="/FileUploadDemo/upload.do" method="POST">
        稱名案檔後載上     : <input name="name" type="text"/><br>
           案檔擇選: <input name="contents" type="file"/><br>
        <input type="submit" value="Submit"/>
    </form>
</body>
</html>



檔的傳上要所擇選以可並,稱名案檔的後傳上定設以可中面頁個這在
   s uccess.jsp    :下如計設則      ,案
 FileUploadDemo                                            success.jsp
<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Upload Success</title>
</head>
<body>
    <h1>File: ${filename} upload successfully.</h1>
</body>
</html>




     的依相到用使案專個這             Commands FileUpload    在要以所,         lib
          括包中錄目   commons-fileupload.jar   及以   commons-io.jar   檔
             。案

                                                                       7 7
7 8
                      單簡為更現實的構架        MVC   讓   7.18 Spring   圖
    J SF     Struts
。等 、 是像,架框 的它其合整中                Web
                                  在何如及以,案方             Spring
決 解的同 不 種 多 供 提 上 術 技 層 在 何 如     View
                                下一看來將節章個一下        Spring
, 些這有 只 不 還 案 方 決 解 的 供 提 所 層 在 ,明說了作 應相及Web       S pring         API
Controller
       的種各與,構架要主的                      Spring Web MVC
                                 於對節章個一這
                                                    7.4 接下來的主題
                      )   – http://openhome.cc      良信林(冊手術技       Spring 2.0

Spring 2.0 技術手冊第七章 - Spring Web MVC 框架

  • 1.
    。別類 的當適用使求需的己自依以可您讓,構架承繼 Controller Controller 的善完個一了供提還 ,外之架框 供提了除 Spring Web MVC 。便方為更上合整的能功多許在,能功器 容 的 IoC 合結,題問架框 Spring 的存現決解能望希,案 Web MVC 方架框 的己自供提也 Web MVC ,) S pring(架框F ramework MVC 的 案 專) Web (碼 始 原 放 開 多 許 有 今 現 , 構 架 的 薦 推 所 O penSource 員人發開數多受 ,時式程用應 發開來以久長是構架 Web Web MVC Spring Web MVC 框架 7
  • 2.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 7.1 Spring Web MVC 入門 的單簡最個一從將,中節小個這在 解了來,式程用應 Spring Web Web MVC 的 及以,式方作運的構架 Spring Web 。構架 現實何如架框Web MVC 7.1.1 使用 Eclipse Web Tools Platform 用使將,式程用應 的章本 Web Eclipse Web Tools Platform ( W TP ) 「的 在以可您,發開行進來 http://www.eclipse.org/webtools/ d ownloads 」 用使將章本。本版的」 「載下區 W ebTools Platform; All-in-one Tomcat 5.5 至請也以所,) Servlet (器容 為作 C ontainer http://tomcat.apache.org/ Tomcat 5.5 。 載下 用使算打果如 Eclipse 裝安式方新更上線的 WTP 下 考 參 以 可 則, :學教音影的址網列 http://eclipse.cdpa.nsysu.edu.tw/technology/phoenix/demos/i nstall-wtp/install-wtp.html 寫撰了為,後之 行執在 WTP Web 的便方些一用使以可,時式程用應 「行執 請 , 合 組 窗 視 具 工 啟開擇選,」 W indow/Open Perspective/Other… :」 J 2EE Perspective 「 7 2
  • 3.
    Chapter 7 SpringWeb MVC 架框 圖 7.1 啟開擇選 J2EE Perspective 動啟接直中 在以可就此如,境環行執 Server 定設要先首 WTP Tomcat 選方下窗視 在請,式程用應 的寫撰所中 在試測以,器容 WTP Web WTP :」 「行執 , 鍵 右 鼠 滑 按 中 窗 視 於 並 , 」 S ervers 「擇 N ew/Server 圖 7.2 增新 Server 境環行執 用使將章本為因 Tomcat 5.5 「在著接以所, N ew Server 擇選中窗視」 「的中」 A pache「 T omcat v5.5 Server :」 7 3
  • 4.
    7 4 : FirstSpringMVC 為稱名案專 Spring Web MVC 個一第設假,稱名案專入輸,後之鈕按 N ext 」 「下按在,案專」 W eb/Dynamic Web Project 「擇選,時案專增新 」 F ile/New/Project… 「行執 在 以 可 , 式 程 用 應 寫 撰 要 中 在 Web WTP 境環行執 Server 了增新 7.4 圖 : 示 所 圖 下 如 後成完 , 增 新 的 境 環 行 執 成完可即,鈕按 Server 」 F inish 「下按著接,夾料資裝安 Tomcat 擇選請,後之鈕按」 「下按 N ext 型類 Server 定設 7.3 圖 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 5.
    Chapter 7 SpringWeb MVC 架框 圖 7.5 態動增新 Web 案專 理管源資了為次這。增新的案專成完可即,後之鈕按」 「下按 F inish , 的依相其及以, 用使接直,便方的上 spring.jar commons-logging.jar jar 。下夾料資 到放 個兩這將請 WEB-INF/lib 圖 7.6 態動 Web 構結案專 7
  • 6.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 式程用應 在置放須必是或,案檔碼始原 WTP 的中 Java 在 Web 資關相 或頁網它其,下之錄目 在增新以可,案檔的下 Classpath src Web 為) (出匯要後以,下之錄目 在增新以可,源 WebContent E xport WAR 為織組案檔關相將動自會 ,時案檔) W eb Application Archive ( W TP Web 。 構結統 系 案 檔 的 式 程 用 應 7.1.2 第一個 Spring Web MVC 程式 先須 必 而 , 源 資 的 需 所至接 連 接 直 不 並 者 用 使 , 中 構 架 Web MVC 在 求請的 者 用 使 斷 判 器 制 控 端 前 由 , ) F ront controller ( 器 制控 端前至接連 達 此藉 ,求 請 理 處 來) D ispatch (件 物 制 控 個 一 哪 給 ) (派 分 要 C ontroller 。 的 目 之源資 求 請 者 用 使 制 控 到 是的色角器制控端前任擔,中架框 Spring Web MVC 的 在 org.spring- 將責負 framework.web.servlet.DispatcherServlet , D ispatcherServlet 是就,步一第的 用 使 以 所 , 件 物制控 給 配 分 求 請 的 戶 客 Spring Web MVC web.xml : DispatcherServlet 義定中 在 FirstSpringMVC web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee → http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <session-config> <session-timeout> 30 </session-timeout> </session-config> 7 6
  • 7.
    Chapter 7 SpringWeb MVC 架框 <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/mvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> 例實的 web.xml 個一了義定中 在 DispatcherServlet "dispatcher- 由會都求請的尾結 Servlet" 至接連有所,到看以可中定設從, *.do 定設來用數參始初 "dispatcherServlet" ,理處來 " contextConfigLocation" 參始初 Bean 置設不果如,稱名與置位的檔義定 "contextConfigLocation" 「取讀,置前為稱名的 用使會設預 DispatcherServlet 則,數 Servlet S ervlet 取讀會則中定設的面上在,檔義定 - servlet.xml 其為作」 Bean 稱名 mvc-config.xml 。義定的中 :是 像 , 源 來 的 檔 義 定 個 多 義 定 以 可 也 您 Bean ... <servlet> <servlet-name>hello</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-config.xml, 7 7
  • 8.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) → /WEB-INF/other-service.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> ... (件物制控至求請配分責負 DispatcherServlet C ontroller 在,) Spring Web MVC 作實要件物制控,中架框 org.springframework.web.servlet. 的作實須必個一有面介 mvc.Controller ,面介 C ontroller handleRequest() :示所 下 如 義 定 其 , 法 方 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; } 行執會,求請的配分 Controller 到收 DispatcherServlet 當 handle- Request() 個一傳回後畢完理處,求請理處來法方 org.springframework. 在現呈要了括包 ,例實的 web.servlet.ModelAndView M odelAndView 。 息 訊 關 相 的 層 它 其 及 以, 料 資 View JSP 的)頁網 如例(層 Model View 個一由將求請的者用使,中 S pring Web MVC 個一第在 H elloController : 示 所 下如作 實 其 , 理 處 來 件 物 FirstSpringMVC HelloController.java package onlyfun.caterpillar; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.mvc.Controller; 7 8
  • 9.
    Chapter 7 SpringWeb MVC 架框 import org.springframework.web.servlet.ModelAndView; public class HelloController implements Controller { private String viewPage; public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception { String user = req.getParameter("user"); return new ModelAndView(viewPage, "user", user); } public void setViewPage(String viewPage) { this.viewPage = viewPage; } } 在定設並,數參求請 的者用使自來了得取,中 Controller 個這在 " user" 個一第的 ModelAndView 構 建 ,中 子 例 個 這 在 , 中 例 實 的 ModelAndView 得取來用定設是數引個二第,徑路)源資或(頁網標目的現呈要為數引 的 料 資 現 呈 層 給 是 數 引 個 三 第 而 , ) (鍵 的 件 物 Model " K ey " View Model 。件物 進,求 請 的 者 用 使 集 收 為 用 作 的 件 物 制 控,下 構 架 Web MVC 在 也,輯邏務商行執中件物制控在應不,作動的關相層 與行 Web 件 物 的 層 務 商 讓 會 這,層 務 商 至 入 侵 的 關 相 Servlet API 讓應不 件物 Servlet API 讓 能 不 如 例,合 耦 生 產 與 HttpServletRequest 。中之件物層務商至定設接直 器容 其在 的 Spring Web MVC ,是處好的 S pring 用使 Controller IoC 相 成完來 入 注 賴 依 其 用 利 並 , 理 管 以 加 來 Bean 的般一 同 如 以 可 , 下 理 管 定設中案檔 在以可您,說來子例的邊這以,入注的件物關 XML Controller 的檔義定 下 一 看 來 ,徑路 頁 網 的 料 資 現 呈 要所, 後 之 畢 完 理 處 求 請 Bean 7
  • 10.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 依,容內 web.xml 在請,定設的中 WEB-INF 立建下錄目 mvc-config.xml :案檔 FirstSpringMVC mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean name="/hello.do" class="onlyfun.caterpillar.HelloController"> <property name="viewPage" value="hello"/> </bean> </beans> 上際實 個一據根須必 DispatcherServlet HandlerMapping 定決,件物 個一哪由求請 Controller ,理處來D ispatcherServlet 用使設預 org.spring- 是就也, framework.web.servlet.handler.BeanNameUrlHandlerMapping 一 哪用 使 定 決 , 的 求 請 者 用 使 及 性 屬 Bean "name" 的時義定在 據根 URL ,時 Controller 求請,中子例個這在如例,例實 個 /FirstSpringMVC/hello.do 為 用使要定決,稱名 DispatcherServlet 據根 "hello.do" "name" "hello.do" 。理處來例實的 Bean 由交求請將是就以所,例實 的 HelloController 由交會 ,後 Controller 回傳 當 ModelAndView D ispatcherServlet 個一置設要需您而因,析解關相的層 ViewResolver 作來件物 View 用使以所,術技層 為作 以將中例範個這在,例實 ViewResolver JSP View 7 1
  • 11.
    Chapter 7 SpringWeb MVC 架框 org.springframework.web.servlet.view.InternalResourceViewResolver , InternalResourceViewResolver 置設要需 "viewClass" 是設預, org.spring- framework.web.servlet.view.InternalResourceView 援支別類個這, Servlet 。) 、 是像(源資關相的術技 JSP S ervlet 與會性屬 、 的 InternalResourceViewResolver "prefix" " suffix" Model- 則,串字 AndView 為 回 傳 訊資徑 路 若 如 例 , 合 結 訊 資 徑 路 的 回 傳 "hello" 。 是 就 徑 路 的 際 實 ,合結 定 設 子 例 的 上 以 與 /WEB-INF/jsp/hello.jsp : 的試測個一寫中 /WEB-INF/jsp/ 在以可後最 hello.jsp FirstSpringMVC hello.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>First Spring MVC</title> </head> <body> <h1>Hello, ${user}!!</h1> </body> </html> 由經,件物 的置設中 ModelAndView 在 Model InternalResourceView- 的取存可中術技 為定設將,析解的 Resolver 及 InternalResourceView JSP 取來 的中術技 用使以可此因,) A ttribute (性屬JSP Expression Language 參 了帶附時 求請在您果如,式程的寫撰所上以依,料資得 hello.do " user" 「的 行執以可,息訊 現出會 的後最則,數 JSP " user" WTP R un/Run As/Run 網將請,器覽瀏 動啟並 On Server 動啟動自會 ,令指」 W TP Tomcat Web 個一, 向指址 http://localhost:8080/FirstSpringMVC/hello.do?user=Justin : 示所下 如 面 畫 考 參 的 行 執 7 11
  • 12.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 圖 7.7 FirstSpringMVC 面畫考參行執 7.1.3 WebApplicationContext 的義定 所 己 自 在 要 想 果 如 Servlet 用使中別類 Spring 則,能功器容的 用 使以可 也 例, org.springframework.web.context.ContextLoaderListener :義定以加籤標 web.xml用使中 在如 <listener> ... <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> ... 取讀會設預 ContextLoaderListener applicationContext.xml 以可您, 在要只,檔義定的己自定指 <context-param> 定指中 "contextConfig- :如例,數參 Location" ... <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/beans-config.xml, → /WEB-INF/demo-service.xml</param-value> </context-param> ... 7 12
  • 13.
    Chapter 7 SpringWeb MVC 架框 的義定自在以可著接 Servlet 用使中 org.springframework.web. context.support.WebApplicationContextUtils 從, 得取中 ServletContext org.springframework.web.context.WebApplicationContext :如例, WebApplicationContext ctx = WebApplicationContextUtils. getRequiredWebApplicationContext( this.getServletContext()); WebApplicationContext 了作實 ApplicationContext 是,面介 Spring 為專 Servlet 的 Web 的計設式程用應ApplicationContext 取在,別類作實 得WebApplicationContext 得取來它用利以可,後之 Bean 的義定中檔義定 Bean :如例,例實 Date date = (Date) ctx.getBean("dateBean"); 援支不在 Listener 如例(上器容的定設 Servlet 2.2 ,)本版的早更以 用使以可 來 org.springframework.web.context.ContextLoaderServlet 的面上代取 ContextLoaderListener :如例,定設的 ... <servlet> <servlet-name>contextLoader</servlet-name> <servlet-class> org.springframework.web.context.ContextLoaderServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> ... 設假,式方態組的整完範示來例範的單簡個一寫撰,述敘的上以合綜 : 示 所 下 如 , 能功時 報 供 提 為 用 作 , 式 程 Servlet 個一了寫撰您 7 13
  • 14.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) WebApplicationContextDemo TimeServlet.java package onlyfun.caterpillar; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context. support.WebApplicationContextUtils; public class TimeServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { WebApplicationContext ctx = WebApplicationContextUtils. getRequiredWebApplicationContext( this.getServletContext()); PrintWriter out = res.getWriter(); out.println(ctx.getBean("dateBean")); } } 了用使中 個這Servlet WebApplicationContext 得取試嘗來 義定中 在以可, "dateBean" web.xml ContextLoaderListener義定 與 Bean :如例,置位的檔 WebApplicationContextDemo web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee → http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <session-config> <session-timeout> 30 </session-timeout> 7 14
  • 15.
    Chapter 7 SpringWeb MVC 架框 </session-config> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/beans-config.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>time</servlet-name> <servlet-class> onlyfun.caterpillar.TimeServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>time</servlet-name> <url-pattern>/time.do</url-pattern> </servlet-mapping> </web-app> 了 定 設,中 性 屬 <context-param> 的 在 "contextConfigLocation" Bean : 示 所 下 如 容 內 的 檔 義 定 ,稱 名 與 置 位 的 檔 義 定 B ean WebApplicationContextDemo beans-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="dateBean" class="java.util.Date" scope="singleton"/> </beans> 7 1
  • 16.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 至接 連 器 覽 瀏 用 使 以 可 TimeServlet 執個一,間時的接連示顯會頁網, :示所下如面畫的行 圖 7.8 WebApplicationContextDemo 面畫考參行執的 7.1.4 Handler Mapping ,時到來求請的戶客當 決件物 D ispatcherServlet 據根 Handler mapping 的 應 對至配 分 求 請 將 何 如 , 定 Controller 常通,說來式程用應 於對, Web 至應對徑路 以是就 URL Controller 。 的設預 DispatcherServlet Handler mapping 是 org.springframework. web.servlet.handler.BeanNameUrlHandlerMapping 在使即以所, Bean 告宣確明有沒中檔義定 BeanNameUrlHandlerMapping 用使會也, BeanNameUrlHandlerMapping 依 Bean 的義定 "name" 決來, 之性屬 URL 個一哪用使定 Controller :如例, ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> <bean name="/hello.do" class="onlyfun.caterpillar.HelloController"> <property name="viewPage" value=”hello”/> </bean> ... 7 16
  • 17.
    Chapter 7 SpringWeb MVC 架框 對 者 用 使,中 定 設 的 面 上 在 /hello.do ,求 請 的 徑 路 D ispatchServlet 都 。理處件物 由交會 HelloController BeanNameUrlHandlerMapping 的單簡是於用適僅, Handler mapping 得 使 它為因 , 式 程 用 應 的 型 小 URL Controller 與 關立 建 接 直 稱 名 別 類 的 的 Spring 在,係 Handler mapping 是的用使常最中org.springframework. 下如子例的用使個一, web.servlet.handler.SimpleUrlHandlerMapping :示所 ... <bean id="urlHandlerMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello.do">helloController</prop> <prop key="/welcome.do">welcomeController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> <bean id="helloController" class="onlyfun.caterpillar.HelloController"> <property name="viewPage" value=”hello”/> </bean> <bean id="welcomeController" class="onlyfun.caterpillar.WelcomeController"> ... </bean> ... 7 17
  • 18.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 的求請是 的 ,中置設的性屬 "mappings" 在 < prop> "key" URL 而, 的 ,稱名 的求請理處上際實定設間 <prop> </prop> 與 Bean < prop> "key" :如例, 用使以可還置設 Wildcard ... <bean id="urlHandlerMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello*.do">helloController</prop> <prop key="/welcome.do">welcomeController</prop> </props> </property> </bean> .... 以,中置設的面上在 hello 的尾結 及頭開 .do URL 給交會都,求請 Bean 的中檔義定 " helloController" 。理處來 義定若 Controller 用 使可則 , 範 規 名 命 守 遵 時 稱 名 Spring 2.0 的增新 org.springframework.web.servlet.mvc.support.ControllerClassName HandlerMapping 寫改以可如例, FirstSpringMVC 的 mvc-config.xml :下如 ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id=”controllerClassNameHandlerMapping” class="org.springframework.web.servlet.mvc. → support.ControllerClassNameHandlerMapping"/> <bean name="helloController" class="onlyfun.caterpillar.HelloController"> 7 18
  • 19.
    Chapter 7 SpringWeb MVC 架框 <property name="viewPage" value="hello"/> </bean> ... 與求請的 將動自會 ControllerClassNameHandlerMapping hello* Controller 尋找試嘗會將求請的 如例,對比稱名別類 hello.do Hello- Controller 則,求請的 是若,的樣同,理處來例實 welcome* Controller- 。理處來例實 ClassNameHandlerMapping 尋找試嘗會 WelcomeController 7.1.5 Handler Interceptor 在是者或,後前的行執 Controller 在果如 View 記些 一 作 算 打 後 之 製 繪 作實以可,作動等求請截攔或錄org.springframework.web.servlet.Hand- 下如義定其,法方個三了範規中面介個這在,面介 lerInterceptor :示所 package org.springframework.web.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; } 7 1
  • 20.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 的回傳,行執被前之求請理處 preHandler() Controller在會 boolean 回傳果如,求請理處來 是或 Handler Interceptor 讓否是定決值 Controller false ,求請理處不就 或 Interceptor 的來下接則, Controller p ostHandler() 在會法方 Controller,行執被後之求請完理處 在會則 a fterCompletion() View 。行執被後之成完製繪 承繼以可您 o rg.springframework.web.servlet.handler.HandlerInter- 方的 要 必 對 針 要 只 您,面 介 ceptorAdapter 了 作 實 它, HandlerInterceptor 作實中當在,案專 改 修以可 如 例 , 義 定 新 重 法 FirstSpringMVC Logging- Interceptor : 錄 記 作來後 、 前 的 理 處 件 物 制 控 被 求 請 在 , HandlerInterceptorDemo LoggingInterceptor.java package onlyfun.caterpillar; import java.util.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. handler.HandlerInterceptorAdapter; public class LoggingInterceptor extends HandlerInterceptorAdapter { private Logger logger = Logger.getLogger(this.getClass().getName()); public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info( handler.getClass().getName() + " ..."); 行執始開 return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 7 2
  • 21.
    Chapter 7 SpringWeb MVC 架框 ModelAndView modelAndView) throws Exception { logger.info( handler.getClass().getName() + " 畢完行執..."); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("畢完理處求請 ..."); } } 個一這用使要 HandlerInterceptor 在須必, Bean ,義定行進中檔義定 :如例 HandlerInterceptorDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="loggingInterceptor" class="onlyfun.caterpillar.LoggingInterceptor"/> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="urlHandlerMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="loggingInterceptor"/> </list> 7 21
  • 22.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) </property> <property name="mappings"> <props> <prop key="/hello.do">helloController</prop> </props> </property> </bean> <bean id="helloController" class="onlyfun.caterpillar.HelloController"> <property name="viewPage" value="hello"/> </bean> </beans> 當; 是 UrlHandlerMapping 的用使所意注SimpleUrlHandlerMapping 控 在,錄 記 行 進 會 都 後 前 的理處 被 求 請 在 , 時 求 請 DispatcherServlet 過透 C onsole :示所下如訊資的到看所) (台制 圖 7.9 HandlerInterceptorDemo 面畫考參行執的 7.1.6 Controller 繼承架構 是的求請理處上際實,後之求請出送者用使當 實以可您, Controller ,中 在,求請理處來面介 Controller 作 Spring C ontroller 容 是 Spring IoC 7 22
  • 23.
    Chapter 7 SpringWeb MVC 架框 的富豐供提 Bean。例實 個一的理管器 S pring Controller 根以可,構架承繼 的需所 成 完 以 , 別 類 個 某承繼 來 求 需 的 上 際 實 據 Controller。理處 :構架承繼的 Spring中 出列下以 Controller 圖 7.10 Spring 中 Controller 構架承繼 介簡別分下以 Controller :用作之別類關相 AbstractController AbstractController 了承繼並,面介 Controller 了作實 WebContentGene- 了供提, rator 直以可您。理處的) Session (化步同與取快 s ynchronized 承繼接 處來法方 AbstractController 義 定 新 重 並,handleRequestInternal() :如例,求請理 public class SomeController extends AbstractController { public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { .... return new ModelAndView("view", "modelName", model); 7 23
  • 24.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) } .. } MultiActionController 的您,時大增模規式程在,別類 個一寫撰求請個一每為果如 Controller Controller用 使 接 直 或 承 繼 以 可。加 增 速 迅 會 將 別 類 MultiActionController 寫撰求請個一每用不而,件物個一同於中集理處求請的關相個數將,別類 。件物制控個一 BaseCommandController 、 A bstractCommandController 使以可則,理管以加中件物 個一至取擷值數參求請將要需果如 Command 一是 ,中 在。別 類 子 的 別 類 BaseCommandController 用 Spring C ommand 至定設並取擷數參求請將責負 JavaBean B aseCommandController , 個 流理處的續後了義定則 Command ,中件物 A bstractCommandController , 義定來 承繼會常通,程 AbstractCommandController CommandController :下如子例個一 public class SomeCommandController extends AbstractCommandController { public SomeCommandController() { setCommandClass(YourCommand.class); } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception { YourCommand your = (YourCommand) command; ... return new ModelAndView(..); } .. } AbstractFormController 7 24
  • 25.
    Chapter 7 SpringWeb MVC 架框 ,理處單表於對 A bstractFormController 單表及,數參求請理處了義定中 。程流面頁的行進要所時敗失或功成交提 SimpleFormController 承 繼 以 可,理 處 單 表 的 單 簡 於 對 SimpleFormController 定 新 重 以 可,別 類 理處己自要果如,法方 doSubmitAction() 義 新重以可則, ModelAndView 。法方 onSubmit() 義定 AbstractWizardFormController 承繼以可,說來頁網的集收料資成完來面畫單表個數要需於對 Abstract- 來能功) (靈精的式程用應面桌像以可您, WizardFormController W izard 。單表作製 個一每,紹介的單簡個作先 的上 以 於 對 邊 這 在 Controller Controller 明 說 續繼將 下 以 , 明 說 的 細 詳有會 都 中 節 一 下 在 別 類 Spring Web MVC 的 API 。 要主 7.1.7 ModelAndView 所時 面 畫 現 呈 , 中 式 程 ModelAndView 了表代別類 Spring Web MVC 能只次一中法方的式程 於由,件物料資 與件物料資 Model View 用使 Java 同 您 便 方 ,件 物 個 兩 這 裝 封 是 用 作 的 ModelAndView 以 所 ,件 物 個 一 傳 回 Model View 。 與 回傳時 被稱名 後之,稱名的ModelAndView括包只是 的單簡最 View View 面介 View resolver 作 實 是 就 也, org.springframework.web.servlet.View 的單簡最,等 或 InternalResourceView 如例,析解例實的 JstlView Model- AndView :下如式方構建 ModelAndView(String viewName) 7 2
  • 26.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 件物 用使以可則,件物料資 的 需 所時面 畫 現 呈 回 返 要 果 如 Model Map 下 用 使 以 可 ,數 引 的 時 構 建 為 作 構 建 在 後 然 ,料 資 集 收 來 ModelAndView :法方構建 ModelAndView 的本版個這面 ModelAndView(String viewName, Map model) 的現 呈 要 在 以 可 後 之 , ) ( 值 與 ) ( 鍵 定 設 中 件 物 Map " K ey " " V alue " 資 個一回傳要您果如,)中頁網 在如例(示顯以加出取中面畫 JSP Model :本版 個這面下用使以可則,稱名的 Model 定指並件物料 ModelAndView ModelAndView(String viewName, String modelName, Object modelObject) 由藉 物料資 modelName 出取中別類作實的 在以可您, View Model 據根並,件 View 現呈等 、頁網 是能可(示顯以加來術技的用使所 JSP P df 。)術技 用使可也別類ModelAndView View 引的時構建為作來件物的面介 : 法 方 構 建的用 可 個 三 是 下 以 , 數 ModelAndView(View view) ModelAndView(View view, Map model) ModelAndView(View view, String modelName, Object modelObject) 作實個一 View 是例實的 org.springframework.web.servlet.view. 成完來式方) RedirectView (發轉用使是設預 M odelAndView , F orward ) (向導新重用使會則,話的 用使,面畫果結的求請 RedirectView R edirect : 如 例 , 果 結 的 求請現 呈 以 , 置 位 面 畫 果結的 定 指 至 導 重 求 請 將 7 26
  • 27.
    7 27 throws Exception { HttpServletResponse res) public ModelAndView handleRequest(HttpServletRequest req, ... " :如例, 鍵 個一生產動自會法方" ,件物 a ddObject() 入加 Model 僅以可您,法方 addObject() 了增新 ,中M odelAndView 在 Spring 2.0 Web 。 址 位 式 程 用 應 的 它 其 至 定 指 以 可 ,頁網 個 一 求 要 新 重 器 覽 瀏由是向導新重, WEB-INF 是像,錄目藏隱的中式程用應 問訪能不 Web 以所,出發器覽瀏由是求請的後向導新重,訊資的向導新重現出會上列址 位的器覽瀏此因,址位的定指所至接連新重會端戶客,址位求請出發新重 器覽瀏端戶客求要會式程用應 ,話的) W eb (向導新重用使 R edirect Web 。 址 位 式 程 用 應 的它其 至 定 指 能 不 , 行 進 中 式 程 用 應 在 能 只 Web 式方發 轉 , 源 資 些 這 得 取 以 可 才 , 理 處 的 與 Controller DispatcherServlet 過透須必而,源資些這求請接直法無就者用使此如,下 WEB-INF 到放源 資 的 取 存 管 控 要 些 一 將 以 可 此 因 , 錄 目 WEB-INF 是像,錄目部內 Web 的定 設 所 式 程 用 應 問訪以 可 , 行 進 內 之 式 程 用 應 在 是 發 轉 且 而 Web ,址位的發轉被現出會不並上列址網,話的式方) (發轉用使 F orward 。錄目式 程用應 是 Web FirstSpringMVC 中其,址位的樣這 MVC/pages/index.htm /FirstSpring- 像須必址位的回傳 getViewPage() 以所, 錄 目 根 的 式 程 用 應 Web是不而,始開錄目根頁網器服伺從須必定設的 ,邊這在 v iewPage ... } new RedirectView(this.getViewPage())); return new ModelAndView( ... public ModelAndView handleRequest(....) ... { ... 架框 Chapter 7 Spring Web MVC
  • 28.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) User user = new User(); ... ModelAndView modelAndView = new ModelAndView(viewPage); modelAndView.addObject(user); return modelAndView; } ... 動自會則,例實 是的 給定設果如 addObject() onlyfun.caterpillar.User 入加果如,稱名生產來稱名面介或別類照按說是就也, 為 鍵 生產 " " " user" null 。 生發會則, IllegalArgumentException 由, 定指不以可還 Spring 2.0 的 ModelAndView View 以可如例,稱名 供提求請據根來 RequestToViewNameTranslator View :寫 撰 下 如 中 檔 定 設 在 <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id=”controllerClassNameHandlerMapping” class="org.springframework.web.servlet.mvc. → support.ControllerClassNameHandlerMapping"/> <bean id="viewNameTranslator" class="org.springframework.web.servlet. → view.DefaultRequestToViewNameTranslator"/> <bean name="helloController" class="onlyfun.caterpillar.HelloController"> <property name="viewPage" value="hello"/> </bean> ... 在 HelloController 化例實中 ModelAndView 定指不若,時 View 例, :如 7 28
  • 29.
    Chapter 7 SpringWeb MVC 架框 ... public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception { ModelAndView modelAndView = new ModelAndView(); ... return modelAndView; } ... 求請果如以所, 了定設於由 ControllerClassNameHandlerMapping 了定設於由,求請理處來 hello.do 讓會則, HelloController RequestTo- 並,時 生產中 ViewNameTranslator 然雖, handleRequest() ModelAndView 了合結(理處來 View 由會但, 定指有沒 hello.jsp InternalResource- ViewResolver 。)定設置後與置前的 7.1.8 View Resolver 的回傳據根 DispatcherServlet ModelAndView 名 析解來例實 View 。件物 的面畫於現呈理處並,稱 Model V iew 作實給託委是析解的稱名 org.springframework.web.servlet.ViewResolver ,例實的面介 View- Resolver :下如義定面介 package org.springframework.web.servlet; import java.util.Locale; public interface ViewResolver { View resolveViewName(String, Locale locale) throws ServletException; } ViewResolver 是例實個一的 以可您, InternalResourceViewResolver 在 viewResolver 與 定設中 "prefix" "suffix" 與置前 的 徑 路 定 設 別 分 , 性 屬 7 2
  • 30.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 樣這,字文置後 viewPage 個給接直,稱名別區要主的徑路打只以可就性屬 :範示的定設 ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> ... 的際實,後完析解稱名在 ViewResolve View 轉的件物 與製繪 Model 作實給交是理處換 ,例實的面介 org.springframework.web.servlet.View View :下如義定面介 package org.springframework.web.servlet; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface View { void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; } 是 的設預 如例 InternalResourceViewResolver "viewClass" Internal- 關相術技層 的它其為性屬 ResourceView 定設以可也, "viewClass" View 外另, 為定設如例,別類 org.springframework.web.servlet.view.JstlView 。術技 的同不用適可,別類作實等 TilesView 、 有還 V elocityView View 用使以可您 org.springframework.web.servlet.view.BeanNameView- Resolver :如例, 7 3
  • 31.
    Chapter 7 SpringWeb MVC 架框 ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.BeanNameViewResolver"/> <bean id="hello" class="org.springframework.web.servlet.view.JstlView"> <property name="url" value=”/WEB-INF/jsp/hello.jsp”/> </bean> ... 的回返 當,中定設的上以在 ModelAndView view 為稱名 "hello" ,時 "id" 。 " hello" 的 為性屬 找尋去會 View Bean 用使以可這,中檔性屬個一至來出立獨義定的 ViewResolver 將以可 來 org.springframework.web.servlet.view.ResourceBundleViewResolver : 如 例 , 術 技 層 示 表 的 同 不 定 設 的 際 實據根 以 可 是 處 好 , 成 達 URL ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.ResourceBundleViewResolver"> <property name="basename" value=”views”/> </bean> ... 在 了定設性屬 ResourceBundleViewResolver 的 "basename" "views" 是也 (稱名 " views" "basename" 用使將這,)值設預的 views.properties 的術技層示表定設來 "viewClass" 個一如例, 與 "url" views.properties 的 :示所下如例範寫撰 hello.class=org.springframework.web.servlet. → view.InternalResourceView hello.url=/WEB-INF/jsp/hello.jsp welcome.class=org.springframework.web.servlet.view.JstlView welcome.url=/WEB-INF/jsp/welcome.jsp 7 31
  • 32.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) other.class=org.springframework.web.servlet.view.VelocityView other.url=/WEB-INF/vm/other.vm 找尋會則, 為若稱名 的中例實 ModelAndView 的回傳在 view "hello" 可您 , 的 定 指 及 例 實 hello.class hello.url 的應對到得來 及 ViewClass URL 為置設上 在, 的同不置設區地或家國的同不為以 View "basename" 以可, "views"是定設系語果如, 取讀會設預示表, views.properties en_US 準它為以可, 是 定 設 系 語 果 如, views_en_US.properties 備準它為 zh_TW 定設域區與置設以可中案檔的應對而, views_zh_TW.properties 備 Locale View 。 的關相 用使以可也 org.springframework.web.servlet.view.XmlViewRe- solver :示所下如例範的定設個一, ... <bean id="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="location" value=”/WEB-INF/demo-views.xml”/> </bean> ... 是設預性屬 ,中定設的面上在 " location" 為定設邊這, views.xml 找尋中 到示表, demo-views.xml demo-views.xml View 例,義定 的 Bean :義定麼這中 demo-views.xml在如 ... <bean id="hello" class="org.springframework.web.servlet.view.JstlView"> <property name="url" value=”/WEB-INF/jsp/hello.jsp”/> </bean> ... 7 32
  • 33.
    Chapter 7 SpringWeb MVC 架框 定設 與 制 機 的 作 運 其 BeanNameViewResolver 的傳回當,的似類是時 為稱名 的中例實 ModelAndView view "hello" 義定 找尋去會則,時 Bean 。定設 的 "id" 為 的中 "hello" View 7.1.9 Exception Resolver 例個這捉捕想您而,外例了出丟中程過行運在 JSP 或頁網 果如 Servlet 定設如例(外法方定設捉捕的外例關有中頁網 與器容用使了除,外 JSP 的素元令指 web.xml 頁網 定設是或,籤標 <error-page> 的 JSP "page" 理處 誤 錯 定 設 中 檔 義 定 的 "errorPage" 在以可也,)性屬 DispatcherServlet 用使如例,例實 的 個一定設,頁網 ExceptionResolver Bean org.springframework.web.servlet.handler.SimpleMappingException- Resolver :示所下如子例的定設個一, ... <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> <bean id="exceptionResolver" class="org.springframework.web.servlet. → handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.sql.SQLException">sqlexception</prop> <prop key="java.sql.IOException">ioexception</prop> </props> </property> </bean> ... 7 33
  • 34.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 使時 生 發 外 例 在 並 , 用應動自會 DispatcherServlet ExceptionResolver 了生發要只,中定設的面上在如例,息訊誤錯示顯來頁網的定指用 了生發而, SQLException 至接連會就, /WEB-INF/jsp/sqlexception.jsp IOException 。 至接連會就, /WEB-INF/jsp/ioexception.jsp 7.2 Controller 實作類別 需 所 作 製 來 求 需 依 以可 , 別 類 關 相 的 面 介 Spring Controller 作實供提 , 理處求 請 的 頁 網 單 表 、 集收數 參 求 請 的 單 簡 是 論 無 , 件 物 Controller 的 以可別類的應對有都中 W izard 在,等計設的頁網 ) (靈精是至甚 Spring 。用應 7.2.1 AbstractController 是別類 org.springframework.web.servlet.mvc.AbstractController 請的者用使了作實式模 Controller 用使,作實單簡的面介 Template Method 請對驗檢、理處的) (頭標取快對了括包,程流的理處求 C aching header ) (化步同與得取的 G ET 、援支的) 、 (法方求 P OST S ession s ynchronized 。別類 用使 以 可 則 , 理 處 作 題議些 這 對 要 需 果 如 , 等 AbstractController 行執 被法方 AbstractController 從 handleRequest() DispatcherServlet : 示所下 如 程 流 作 工 的 始 開 1. DispatcherServlet 。法方 行執 handleRequest() 2. 援 支 不 法 方 果 如,法 方 求 請 的 援 支 驗 檢 來 定 設 的 "supportedMethods" 據根 ServletException 。 出丟則 3. 得取試嘗, 用使要需否是求請定決定設的 "requireSession" 據根 Session Session 。 出丟則 Session 得取有沒果如, ServletException 7 34
  • 35.
    Chapter 7 SpringWeb MVC 架框 4. 據根 (頭標取快定設否是定決定設的 "cacheSeconds" C aching header。) 5. 叫呼 據根,法方 handleRequestInternal() "synchronizeOnSession" 是定決 對否 Session 。) (化步同行進 s ynchronized 於對 AbstractController 以可就解了的本基個有要只,程流作工的別類 承繼 接 直 以 可 , 了 AbstractController 義定新重並,別類 handleRequest- :如例,法方 Internal() public class SomeController extends AbstractController { protected ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { .... return new ModelAndView("view", "modelName", model); } .. } 方些一的好義定經已作操接直以可,話的別類 AbstractController 用使 , 式 方 求 請 的 許 允 所 定 設, 法 方 叫呼以可如例,法 setSupportedMethods() 、 、 援 支只則 , 話 的 寫 撰 下 如 若 時 作 實 Controller 如例 GET P OST H EAD :求請的 package onlyfun.caterpillar; ... public class HelloController extends AbstractController { ... public HelloController() { this.setSupportedMethods( new String[] {"GET", "POST", "HEAD"}); } protected ModelAndView handleRequestInternal( HttpServletRequest req, HttpServletResponse res) throws Exception { ... } } 7 3
  • 36.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 則,話的求請式方的許允不以果如 Controller 出丟會候時的理處在 org.springframework.web.servlet.support.RequestMethodNotSupported- Exception 。外例的 7.2.2 MultiActionController 與 ParameterMethodName- Resolver 個一寫撰理處的求請個一每為若,大越來越模規的式程用應果如 的多越來越有中式程用應 Controller 到現發您,的快很,別類 Web 如例,別類個一在織組以可是責職些一的中當上實事而,別類 Controller 個一在織組以可就,法方等 、 、 的關相作操庫料資與 list() a dd() d elete() 。別類 :別 類 子 個 一 的 別 類 AbstractController 用使以可您 o rg.springframe- 在您讓以可它。 work.web.servlet.mvc.multiaction.MultiActionController 的 中當行 執 來 求 請 的 者 用 使據根 並 , 法 方 個 多 義 定 中 別 類 Controller 個一 。法方個某 個一合配要您, MultiActionController 用使要 org.springframework. ,例實的 web.servlet.mvc.multiaction.MethodNameResolver M ultiAction- Controller 是別類 的用使設預 MethodNameResolver org.springframework. 個 這, web.servlet.mvc.multiaction.InternalPathMethodNameResolver 行執斷判來稱名案檔的求請後最,中址網的給所據根以可別類 Controller 行執會求請的 /test.do 如例,法方個一哪的中 test (HttpServletRequest, HttpServletResponse) 用使會不常通但。法方 InternalPathMethodName- 是像,點優些一的 Resolver 用使了去失就這為因, MultiActionController 。法 方 的 行 執 要 所 定 決來數 參 求 請 的 者 用 使 依 7 36
  • 37.
    Chapter 7 SpringWeb MVC 架框 用使在常通 MultiActionController 配搭會時 org.springframework. web.servlet.mvc.multiaction.ParameterMethodNameResolver 是或 o rg. springframework.web.servlet.mvc.multiaction.PropertiesMethodName- 行執要定決數參以,數參求請個一據根是都別類個兩, Resolver Controller 可, 例 為 以 先 邊 這, 法 方 個 一 哪 的 中 別 類 ParameterMethodNameResolver Bean :寫撰麼這中檔義定 在以 MultiActionDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/book.do">bookController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="paraMethodResolver" class="org.springframework.web.servlet.mvc. → multiaction.ParameterMethodNameResolver"> <property name="paramName" value="action"/> <property name="defaultMethodName" value="list"/> </bean> 7 37
  • 38.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <bean id="bookController" class="onlyfun.caterpillar.BookController"> <property name="methodNameResolver" ref="paraMethodResolver"/> <property name="testPage" value="test"/> </bean> </beans> 設性屬 用 使 ,中 義 定 的 " paraMethodResolver" Bean 在 "paramName" 沒中求 請 是 若 , 法 方 的 行執 要 所 定 指 數 參 HTTP "action" 用使中求請 在定 方的定設所性屬 "action" 用使會則,數參 定指有 "defaultMethodName" list() 。法方 是的定設邊這,法 在義定中當,別類 BookController 承繼 MultiActionController "action" : 如 例 , 法 方的行 執 要 所 下 定 指 數 參 MultiActionDemo BookController.java package onlyfun.caterpillar; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc. multiaction.MultiActionController; public class BookController extends MultiActionController { private String testPage; public ModelAndView list(HttpServletRequest req, HttpServletResponse res) { return new ModelAndView( this.getTestPage(),"executed", "list"); } public ModelAndView add(HttpServletRequest req, HttpServletResponse res) { 7 38
  • 39.
    Chapter 7 SpringWeb MVC 架框 return new ModelAndView( this.getTestPage(),"executed", "add"); } public ModelAndView delete(HttpServletRequest req, HttpServletResponse res) { return new ModelAndView( this.getTestPage(),"executed", "delete"); } public String getTestPage() { return testPage; } public void setTestPage(String testPage) { this.testPage = testPage; } } 與 括包須必,中法方的義定到意注 HttpServletRequest HttpServlet- 。本版的 Response 數參 個 三 第 有 帶 用 使 以 可 也 , 數 參 的 HttpSession 試測於用,例範的單簡個一是只別類 BookController 的義定所上以 目示表,串字個一定設是只理處的作所它,作運的 MultiActionController 者 用 使 示 顯 以 用 , 頁 網 的 用 試 測 個 一 計 設 以 可,稱 名 法 方 的 行 執 所 前 JSP :如 例 , 法 方 的 求 請 所 MultiActionDemo test.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>MultiAction Test Page</title> </head> <body> <H1> "${executed}" method is executed.</H1> 7 3
  • 40.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) </body> </html> 行執個一,數參求請上附中址網在以可,子例的求請出發個看際實來 :示 所 下 如 面 畫 考 參 的 圖 7.11 MultiActionDemo 果結行執的案專 7.2.3 MultiActionController 與 PropertiesMethodNameResolver 寫撰是不而,中件物) (託委個一在織組法方有所將以可也您 d elegate , 法方的 定 指 行 執 件 物 個 這給託 委 , 時 到 來 求 請 當 , 中 別 類 Controller 在 例,件 物 託 委 至 考 參 性 屬 的 MultiActionController "delegate"定設要只您 : 下如計 設 以 可 件 物 託 委 如 MultiActionDemo2 BookDelegate.java package onlyfun.caterpillar; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; public class BookDelegate { private String testPage; public ModelAndView list(HttpServletRequest req, HttpServletResponse res) { 7 4
  • 41.
    Chapter 7 SpringWeb MVC 架框 return new ModelAndView( this.getTestPage(),"executed", "list"); } public ModelAndView add(HttpServletRequest req, HttpServletResponse res) { return new ModelAndView( this.getTestPage(),"executed", "add"); } public ModelAndView delete(HttpServletRequest req, HttpServletResponse res) { return new ModelAndView( this.getTestPage(),"executed", "delete"); } public String getTestPage() { return testPage; } public void setTestPage(String testPage) { this.testPage = testPage; } } 承繼用不在現 MultiActionController 義定來別類 Controller 而,別類 義定 接 直 中 檔 義 定 在 是 :例實的 MultiActionController MultiActionDemo2 mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> 7 41
  • 42.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <props> <prop key="/book.do">bookController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="paraMethodResolver" class="org.springframework.web.servlet.mvc. → multiaction.ParameterMethodNameResolver"> <property name="paramName" value="action"/> <property name="defaultMethodName" value="list"/> </bean> <bean id="bookDelegate" class="onlyfun.caterpillar.BookDelegate"> <property name="testPage" value="test"/> </bean> <bean id="bookController" class="org.springframework.web.servlet.mvc. → multiaction.MultiActionController"> <property name="methodNameResolver" ref="paraMethodResolver"/> <property name="delegate" ref="bookDelegate"/> </bean> </beans> 用使以可您 MultiActionDemo 這,果結現呈來頁網 的中案專 test.jsp 與果結行執的式程個 MultiActionDemo 圖考參以可,的同相是案專 7.11 。面畫的 7 42
  • 43.
    Chapter 7 SpringWeb MVC 架框 用使以可也,式程的面上 PropertiesMethodNameResolver 將如例, Bean:容內的下以為寫改檔義定 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/*book.do">bookController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> <bean id="propMethodResolver" class="org.springframework.web.servlet.mvc. → multiaction.PropertiesMethodNameResolver"> <property name="mappings"> <props> <prop key="/listbook.do">list</prop> <prop key="/addbook.do">add</prop> <prop key="/deletebook.do">delete</prop> </props> </property> </bean> <bean id="bookDelegate" class="onlyfun.caterpillar.BookDelegate"> <property name="testPage" value=”test”/> 7 43
  • 44.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) </bean> <bean id="bookController" class="org.springframework.web.servlet.mvc. → multiaction.MultiActionController"> <property name="methodNameResolver" ref="propMethodResolver"/> <property name="delegate" ref="bookDelegate"/> </bean> </beans> 給交會都求請的尾結為 有所,定設的上以據根 book.do bookController 同 依 ,法 方 的 行 執 會 ,時 /listbook.do 求 請 而 ,理 處 來bookDelegate list() 或 行執來 或 用使別分以可,理道的樣 /addbook.do /deletebook.do a dd() l ist() : 示 所 下 如 面 畫考參 的 行 執 個 一 , 法 方 圖 7.12 用使 PropertiesMethodNameResolver 果結行執的 7.2.4 ParameterizableViewController 類子的別類 是別類 ParameterizableViewController AbstractController 這當,性屬 的它 定 設 , 義 定 中 檔 義 定 在接 直 以 可 , 別 Bean "viewName" , 頁網的 定 指 向 導 接 直 定 設 的 Controller 據根會,時行執 "viewName" 個 個一計設以可如例,求請 頁網 對接直免避來用以可是處好的它用使 JSP 將以可,制控 index.jsp 過透都求請的有所讓了為, DispatcherServlet :義定麼這中檔義定 在接直並,下 index.jsp WEB-INF 在置放 Bean 7 44
  • 45.
    Chapter 7 SpringWeb MVC 架框 ... <beans> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.do">indexController</prop> .... </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value=”/WEB-INF/jsp/”/> <property name="suffix" value=”.jsp”/> </bean> <bean id="indexController" class="org.springframework.web.servlet. → mvc.ParameterizableViewController"> <property name="viewName" value=”index”/> </bean> <beans> 是求請址網的接連當,定設的上以依 /index.do 定指所至接連會則,時 。頁網 的 /WEB-INF/jsp/index.jsp 7.2.5 AbstractCommandController 數參 求 請 供 提 者 用 使 到 遇 當 , Controller 是或 用使 AbstractController 這 將算打 果 如 , 數 參 求 請 得 取 中 件 物 從行自須必,時 HttpServletRequest 等換轉態型行進或輯邏關相寫撰行自須必,件物個某至定設數參求請些 。作動 7 4
  • 46.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 承繼以可 org.springframework.web.servlet.mvc.AbstractCom- 當,件物 mandController 個一供提並,別類 作實來 Controller Command 稱名數 參 求 請 對 比 著 試 會 ,時到來求請者用使 A bstractCommandController 對叫呼並,)稱名法方 Command 是就也(稱名法方 Setter 的上 setXXX 與 會 也,態 型 本 基 是 數 參 的 上 Setter 果如,值數參求請定設法方 Setter 的應 。 態 型 的 應 對為值 數 參 求 請 換 轉 動 自 :別類 為 作 別 類 個 一 了 計 設您設 假 , 說 來 子 例 個 舉 User Command AbstractCommandDemo User.java package onlyfun.caterpillar; public class User { private String name; private String password; public void setName(String name) { this.name = name; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public String getPassword() { return password; } } 了括包中求請 果如 "name" 與 "password" 為 裝封要想數參 些這而,數 參 User 承 繼則, 例 實 AbstractCommandController 使以可 , 時 作實 Controller 7 46
  • 47.
    Chapter 7 SpringWeb MVC 架框 用 setCommandClass() 定指 來 Command 的它義定新重並,別類 handle() 方 :如例 ,法 AbstractCommandDemo UserController.java package onlyfun.caterpillar; import java.util.HashMap; import java.util.Map; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. mvc.AbstractCommandController; import org.springframework.validation.BindException; public class UserController extends AbstractCommandController { private String userPage; public UserController() { setCommandClass(User.class); } protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception { User user = (User) command; Map model = new HashMap(); model.put("name", user.getName()); model.put("password", user.getPassword()); return new ModelAndView(getUserPage(), "userInfo", model); } public void setUserPage(String userPage) { this.userPage = userPage; } public String getUserPage() { 7 47
  • 48.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) return userPage; } } 並,例實的 了得取接直,中法方 UserController 的 handle() Command 法方 與 作操接直,後之 為面介作操換轉在 User getName() getPassword() 頁網 在以,訊資集收來件物 個一了用使上以在,數參求請得取來 Map JSP : 下 如 計 設 頁 網 設假 , 訊 資 些 這 現 呈 中 JSP AbstractCommandDemo userInfo.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>AbstractCommandController Demo</title> </head> <body> <h1> :稱名 ${userInfo['name']}</h1> <h1> :碼密 ${userInfo['password']}</h1> </body> </html> 在以可著接 Bean 的關相定設中檔義定 Bean :示所下如,訊資 AbstractCommandDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> 7 48
  • 49.
    Chapter 7 SpringWeb MVC 架框 <property name="mappings"> <props> <prop key="/user.do">userController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="userController" class="onlyfun.caterpillar.UserController"> <property name="userPage" value="userInfo"/> </bean> </beans> :數 參 求 請 上 附 列 址 網在接 直 時 求 請 在 , 面 畫果結 的 行 執 個 一 看 看 來 圖 7.13 AbstractCommandDemo 果結行執的案專 7.2.6 AbstractFormController 承繼過透常通,求需單表的單簡於對 org.springframework.web.servlet. 或 義定新重並, mvc.SimpleFormController 義定來 Controller onSubmit() 定 程流理 處 單 表 的 正 真 上 際實而 , 能 功 單 表 成 完 來 法 方 doSubmitAction() 7 4
  • 50.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) , 在義 org.springframework.web.servlet.mvc.AbstractFormController :明說的中當下一理整邊這,用作之法方的串連一其明說有,中件文 在 API 1. 。例實的 個一傳回要,法方 formBackingObject() 行執 commandClass 2. ,作 動 等 化 式 格 作 的 定 特 initBinder() 對 您 許 允,法 方 行執 Command Field 。定設的 或態型本基非供提,等式格錢金、式格期日如例 String 3. 。現展的單表於用,件物 個一回返,法方 showForm() 行執 View 4. 用應則, 為定設被性屬 "bindOnNewForm" 果如 true ServletRequest- 行執且並,件物單表的新個一入填來數參求請始初據根 DataBinder onBindOnNewForm() 。法方 5. showForm() 程過的單表現展在果如,法方 行執會法方 referenceData() :如例,件物 個一傳回以可,料資關相些一要需,中 Map protected Map referenceData( HttpServletRequest request) throws Exception { Map ref = new HashMap(); ref.put("defalutUser", "guest"); return ref; } 用使中頁網 在以可就,來一樣這 JSP ${defaultUser} ,料資現呈來法寫的 。 是會值的得取所如例 "guest" 6. Model 。寫填行進並單表到看以可者用使,現展被件物 : 行 進 程 流 的下以 依 會 將 , 單 表 出 送後之 單 表 完 寫 填 者 用 使 1. 式方的樣這 用想不果如, 用使常通,出送單表的者用使受接 POST POST 。法方 義定新重以可,單表出送否是者用使斷判來 isFormSubmission() 2. 以法方 行 執 會 則,定 設 有 沒 性 屬 "sessionForm" 果如 formBackingObject() 執則到找有沒果如,件物單表得取中 從試嘗則否,件物單表得取 session 7
  • 51.
    Chapter 7 SpringWeb MVC 架框 行 handleInvalidSubmit() 重並件物單表的新立建 試嘗是作動的設預,法方 。單表寫填新 3. ServletRequestDataBinder 。件物單表入填數參求請的前目據根 4. 行 進 件 物 單 表 對 以 可 前 之 料 資 證 驗,後 之 料 資 定 綁 在,法 方 onBind() 行執 。作動改修的訂自些一 5. 。器證驗用使則,定設被性屬 "validateOnBinding" 果如 6. 些 一 作 件 物 單 表 對 後 之 料 資 證 驗 在 您 許 允,法 方 onBindAndValidate() 行執 。理處 7. 要別類子,法方 行執後最,畢完理處件物單表 processFormSubmission() 。求請的者用使成完以,法方個這義定新重 7.2.7 SimpleFormController 是 org.springframework.web.servlet.mvc.SimpleFormController AbstractFormController 類個這承繼接直以可單表的單簡於對,別類子的 義定新重並,別 請的者用使理處以法方 onSubmit() doSubmitAction() 或 ,求 S impleFormController :的 樣 這 是 程 流 理 處 的 1. processFormSubmission() 行執 驗檢以 Errors 時證驗或定綁在看看,件物 。誤錯的何任無有 2. 。面頁的定設所 傳回,生發誤錯有果如 "formView" 3. 也則, 傳回並義定新重被 據根 isFormChangeRequest() 果如 request true 讓, 行執會前之 "formView" 到 回 在, 到回會 "formView" onFormChange() 。件物單表正修會機有您 4. 、 有帶行執會則,生發誤錯有沒果如 HttpServletRequest H ttpServlet- 帶僅行執是設預, Response 的數參 O bject 、 、 B indException onSubmit() 有只行執是設預者後而, Object 的 BindException 及 onSubmit() Object 7 1
  • 52.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 義 定 新 重 慮 考 以 可, onSubmit() 的 定 設 向 導 是 設 預, 的數參 "successView" 向導會設預, doSubmitAction() 回返用不, ModelAndView "success- 。用使以可時件物料資 View" 何任送傳"successView" 向 要 需 不 在, Model 範 示 以 , 式 程入登 單 表 個 一 作 實 下 以 SimpleFormController ,用作的 : 個一計設先首 form.jsp SimpleFormDemo form.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Login Form</title> </head> <body> <h1> </h1> 單表入登 :碼密與稱名者用使入輸請 <p> <form name="loginform" action="/SimpleFormDemo/login.do" method="POST"> 稱名 <input type="text" name="username"/><br> 碼密 <input type="password" name="password"/><br> <input type="submit" value=" "/>定確 </form> 。中面頁個這到回再會誤錯入輸:意注 </body> </html> 數參個兩遞傳中單表 "username" 的單表意注, "password" 與 "method" 樣這, 為定設性屬"POST" Spring 看 先。中 件 物 單 表 入 填 數 參 求 請 將 會 才 :寫撰的 看 LoginController 7 2
  • 53.
    Chapter 7 SpringWeb MVC 架框 SimpleFormDemo LoginController.java package onlyfun.caterpillar; import org.springframework.web.servlet. mvc.SimpleFormController; import org.springframework.web.servlet.*; public class LoginController extends SimpleFormController { public LoginController() { setCommandClass(LoginForm.class); } protected ModelAndView onSubmit( Object command) throws Exception { LoginForm form = (LoginForm) command; if("caterpillar".equals(form.getUsername()) && "123456".equals(form.getPassword())) { return new ModelAndView( getSuccessView(),"user", form.getUsername()); } else { return new ModelAndView(getFormView()); } } } ,件物單表了表代件物個這,件物 onSumit() 收接法方 command 的義定中 getSuccessView() 是 與 getFormView() SimpleFormController 在接直以可會待,頁網標目的敗失與證驗過通示表別分,法方個兩 Bean : 的 單 簡個是 只 它 , 件 物 單 表 看看來 先 , 義 定 中 檔 義 定 JavaBean SimpleFormDemo LoginForm.java package onlyfun.caterpillar; public class LoginForm { 7 3
  • 54.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) private String username; private String password; public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public String getPassword() { return password; } } 看看來下接 Bean :的寫撰何如是檔義定 SimpleFormDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/login.do">loginController</prop> </props> </property> </bean> <bean id="viewResolver" 7 4
  • 55.
    Chapter 7 SpringWeb MVC 架框 class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="loginController" class="onlyfun.caterpillar.LoginController"> <property name="successView" value="success"/> <property name="formView" value="form"/> </bean> </beans> 了義定中檔義定 "successView" 與 "formView" 中其, form.jsp 已前之 下一 看 來 , 成 完 寫 撰 經 success.jsp :寫撰的 SimpleFormDemo success.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Login Success</title> </head> <body> <H1> !囉哈 ${user} </H1> !! !物禮秘神的您是這 ^o^ </body> </html> 求請接直 login.do 入登 單 表 傳 回 會 以 所 ,查檢 入 登 過 通 未 於 由 , 話 的 :示所下如,面畫 7
  • 56.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 圖 7.14 SimpleFormDemo 單表入登的案專 的 敗 失 入 登,稱 名 的 者 用 使 示 顯 並 入 進 會,話 的 功 成 入 登 success.jsp 如面畫的功成入登,單表入登的來原到回會,定設的 "formView" 依,話 :示所下 圖 7.15 SimpleFormDemo 面畫功成入登的案專 7.2.8 AbstractWizardFormController org.springframework.web.servlet.mvc.AbstractWizardFormCont- 卷問於用常通,) roller (靈精的式程用應面桌如出計設您讓以可 W izard 卷問將如不,容內卷問的有所現呈單表個一用使其與,時長當相容內單表 承繼以可您,卷問成完頁一頁一者用使讓,面畫個數作分容內 Abstract- 是的義定中當,法方 義定新重並, WizardFormController processFinish() : 如 例 ,理處 的 後 交 提 卷 問 部 全 7 6
  • 57.
    Chapter 7 SpringWeb MVC 架框 AbstractWizardDemo WizardController.java package onlyfun.caterpillar; import java.util.*; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. mvc.AbstractWizardFormController; import org.springframework.validation.BindException; public class WizardController extends AbstractWizardFormController { private String successView; public WizardController() { setCommandClass(Questionnaire.class); } protected ModelAndView processFinish( HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception { Questionnaire questionnaire = (Questionnaire) command; Map model = new HashMap(); model.put("q1", questionnaire.getQuestion1()); model.put("q2", questionnaire.getQuestion2()); model.put("q3", questionnaire.getQuestion3()); return new ModelAndView(getSuccessView(), "ans", model); } public void setSuccessView(String successView) { this.successView = successView; } public String getSuccessView() { return successView; } } 7 7
  • 58.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 個 一在集 收 果 結 卷 問 的 有 所 Command 結將 是 只 式 程 的 面 上 , 中 件 物 在以,中件物 在定設並得取果 Model View 別類的 ,料資現呈上 C ommand :下如計設 AbstractWizardDemo Questionnaire.java package onlyfun.caterpillar; public class Questionnaire { private String question1; private String question2; private String question3; public void setQuestion1(String question1) { this.question1 = question1; } public void setQuestion2(String question2) { this.question2 = question2; } public void setQuestion3(String question3) { this.question3 = question3; } public String getQuestion1() { return question1; } public String getQuestion2() { return question2; } public String getQuestion3() { return question3; } } 7 8
  • 59.
    Chapter 7 SpringWeb MVC 架框 定 設 由 藉,中 檔 義 定 在 範 規 是 程 流 的 卷 問 Bean AbstractWizardForm- Controller :如例,定決來性屬 "pages" 的 AbstractWizardDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/wizard.do">wizardController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="wizardController" class="onlyfun.caterpillar.WizardController"> <property name="successView" value="success"/> <property name="pages"> <list> <value>start</value> <value>question1</value> <value>question2</value> <value>question3</value> </list> </property> </bean> </beans> 7
  • 60.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 、 、 依將卷問,定設的上以依 、 start.jsp q uestion1.jsp q uestion2.jsp q ues- :寫撰的 tion3.jsp 看看先首,成完來序順的 start.jsp AbstractWizardDemo start.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Insert title here</title> </head> <body> <form name="questionform" action="/AbstractWizardDemo/wizard.do" method="POST"> !卷問寫填您迎歡 <input type="submit" value="Start" name="_target1"/> </form> </body> </html> 網 的 置 位 引 索 中 檔 定設得 取 會 設 預 , 時 器 制 控 Wizard 至接連您當 0 之面頁的示展要個一下定決,面頁明說卷問或迎歡是常通面頁個一第,頁 , 數參求 請 的 碼 號 個 一 著 跟 並 , 頭 開 個 一無有 中 求 請 於 在 , 法 方 "_target" 的面上,序順的 "_target1" 中 檔定設 在 示 表 碼 號 , 定 設 的 樣 這 如例 <list> Start :面 頁 個 二 第 示 顯 會 , 後 鈕 按 下 按 在 頁 網 AbstractWizardDemo question1.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Question 1</title> 7 6
  • 61.
    Chapter 7 SpringWeb MVC 架框 </head> <body> <form name="questionform1" action="/AbstractWizardDemo/wizard.do" method="POST"> 一題問 <input type="text" name="question1"/><br> <input type="submit" value="Previous" name="_target0"/> <input type="submit" value="Next" name="_target2"/> </form> </body> </html> 設預所法方 "_target" 是面頁的示顯定決來碼號與 依 getTaretPage() 數參個一哪由面頁個一下定決以法方個這義定新重以可也,話的要必,的 的 卷 問 回 返 會,話 的 鈕 按 question1.jsp 下 按,中 計 設 的 Previous 在,定 決 設的 ,頁一下的卷問回返會,話的鈕按的 下按,頁一上 Next q uestion2.jsp 案專 中 碟 光 看 觀 行 自 請 , 幅篇省 節 為 , 似 類 是 也 計 AbstractWizardDemo question2.jsp 。案檔 的 , 數參求請有否是中求請驗檢於在,式方的卷問成完否是定決 "_finish" 最是 ,法方 行 執 會就, 值 個 這 到 查 檢 果 如 processFinish() q uestion3.jsp : 的 寫 撰 何 如 是它看 看 來 , 卷 問 個 一 後 AbstractWizardDemo question3.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Question 3</title> </head> <body> <form name="questionform3" action="/AbstractWizardDemo/wizard.do" method="POST"> 三題問 <input type="text" name="question3"/><br> <input type="submit" value="Previous" name="_target2"/> 7 61
  • 62.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <input type="submit" value="Finish" name="_finish"/> </form> </body> </html> 個一有帶要卷問的出送個一後最得記 行執會才,數參 "_finish" 的 AbstractWizardFormControlle processFinish() 個一計設後最,法方 success.jsp :果結示顯來 AbstractWizardDemo success.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Success</title> </head> <body> <H1>Q1: ${ans.q1}</H1> <br> <H1>Q2: ${ans.q2}</H1> <br> <H1>Q3: ${ans.q3}</H1> <br> </body> </html> : 示 所 下 如 面 畫果結 的 後 交 提 卷 問 個 一 圖 7.16 AbstractWizardDemo 面畫果結交提的案專 7 62
  • 63.
    Chapter 7 SpringWeb MVC 架框 個一計設中卷問在以可也您 Cancel 出送,後鈕按該下按在,鈕按 "_cancel":如例,數參求請 .... <form name="questionform3" action="/AbstractWizard/wizard.do" method="POST"> .... <input type="submit" value="Cancel" name="_cancel"/> </form> .... 行執會則,時數參求請 "_cancel" 有帶中求請當 processCancel() 方 :面頁 的 時 始 開 卷 問 回 送者用 使 將 如 例 , 法 方 個這義 定 新 重 以 可 您 , 法 ... protected ModelAndView processCancel( HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception { return new ModelAndView("start"); } ... 7.2.9 ThrowawayController org.springframework.web.servlet.mvc.throwaway.ThrowawayCon- ,義定面介的立獨個一是而,中構架承繼 troller Spring的 在不並 Controller ,用使複重並生產式方的例單以是不別類的面介該作實 T hrowaway- 使複重會不,丟就了用且,件物的新生產要都時求請次一每在 Controller 的供提 (因原的 有帶上稱名是也這,用 " Throwaway" T hrowawayController 。)件物 Webwork 的式形 似類是 Action 7 63
  • 64.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) ThrowawayController :下如義定的面介 package org.springframework.web.servlet.mvc.throwaway; import org.springframework.web.servlet.ModelAndView; public interface ThrowawayController { ModelAndView execute() throws Exception; } 作實須必別類的面介 ThrowawayController 作實 execute() 可,法方 得使這,數參的何任帶不中法方 execute() 到看以 易 ThrowawayController 、 有須必 Controller像要需不,試測於 HttpServletRequest H ttpServlet- Response 。例實的 ,話的數參求請集收要果如,數參的何任有沒上法方 execute() 悉熟點這(用作的 ThrowawayController 具兼也身本 Command Webwork : 個 一 作 實 下 如 以 可如例 , ) 生 陌 不 並 人 的 ThrowawayController .... public class SomeController implements ThrowawayController { private String someParam; public ModelAndView execute() throws Exception { .... return new ModelAndView(...); } public void setSomeParam(String someParam) { this.someParam = someParam; } .... } 7 64
  • 65.
    Chapter 7 SpringWeb MVC 架框 至定設之將會,時數參的 有帶中數參求請當 "someParam" Throwa- wayController 。中法方 的應對 setSomeParam() 將須必 Bean ,是的意注須必中檔義定 定設在 T hrowawayController 用 ,例實 的 新 個 一 生 產 要 求 請 的 次 一 每 , "scope" "singleton" 為定設性屬 :如例,丟即過 ... <bean id="someController" class="onlyfun.caterpillar.SomeController" scope="singleton"> .... </bean> ... DispatcherServlet 用使會設預 org.springframework.web.servlet.mvc. 的下系體承 繼 SimpleControllerHandlerAdapter 得使這, Controller Controller 為接直以可都別類 訴 告 要 了 為 但 ,用 使 DispatcherServlet DispatchServlet 用使 ThrowawayController :如例,告宣中檔義定 在須必,Bean ... <bean id="throwawayHandler" class="org.springframework.web.servlet.mvc. → throwaway.ThrowawayControllerHandlerAdapter"/> <bean id="simpleHandler" class="org.springframework.web.servlet. → mvc.SimpleControllerHandlerAdapter"/> ... 用使以可 ,中定設的面上在 D ispatcherServlet ThrowawayController , 入加再則,系體承繼的面介 合混要您果如 Controller SimpleController- 。用使合混以可就 種兩此如, HandlerAdapter Handler 7 6
  • 66.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 7.3 搭配 Controller 的相關類別 ) 、 ( 證驗 用使 配 搭 上 器 在何如紹介將,中節小個這在 Controller Validator 作實來 的 用使何如及以,換轉態型的料資 Command 作實何如 Spring API 。能功傳上案檔 7.3.1 實作 Validator 個 一 配 搭 以 可,時 SimpleFormController 用使 org.springframework. 工證驗料資端服伺的本基作您助幫,件物作實的面介 validation.Validator 單表 行 進 要 需 給 入 注 為 作 之 將 ,Validator 的用通 個 一 計 設 以 可 , 作 Bean Bean 。件物 它其的證驗 : 示 所 下 如義定 其 , 法 方 的 作 實 須 必 個 兩 有 面 介 Validator package org.springframework.validation; public interface Validator { boolean supports(Class clazz); void validate(Object obj, Errors errors); } 件物 的 入 傳 所 對 援 支 否 是 示 表 , 值 supports() 個一傳回法方 boolean 證驗行進法方 用 使 會 才 , 下 況 情 的 回傳 在 有 只 , 證 驗 行 進 true validate() 它對以 可 您,件 物 單 表 的 入 傳 示 表 ,中 數 參 的 法 方 validate() o bj 在,作 工 或 的 用 使 以 可 , 話 的 誤 錯有果 如 , 證 驗 些 一 行 進 Errors reject() reject- 錯括包中件物 Value() 若 , 中理處 的 續 後 在 , 息 訊 誤 錯 入 加 法 方 等 errors 。面頁的定設所 getViewPage() 到回會,息訊誤 7 66
  • 67.
    Chapter 7 SpringWeb MVC 架框 :作 實 的 單 簡 個 一 看 來 package onlyfun.caterpillar; import org.springframework.validation.Validator; import org.springframework.validation.Errors; public class LoginValidator implements Validator { public boolean supports(Class clazz) { return clazz.equals(LoginForm.class); } public void validate(Object obj, Errors errors) { LoginForm form = (LoginForm) obj; if(form.getPassword().length() < 4 ) { errors.rejectValue("password", "less-than-four", null, " 元字個四於小得不碼密 "); } } } 使來案專 的紹介 配搭以可別類 Validator 7.2.7 個這 SimpleFormDemo 格的碼密查檢是像,件條等性全安、性備完的料資查檢在是常通證驗,用 處的 是 該 應 這 ,確正 否 是 碼 密 與 稱 名 者用使 於 至 , 例 一 是 就 式 Controller 。作工理 中檔義定 在要只, 用使來 SimpleFormController 配搭 Validator Bean ,可即它到考參 Validator Bean 讓及以,義定 的 入加 SimpleFormController :如例 ... <bean id="loginValidator" class="onlyfun.caterpillar.LoginValidator"/> <bean id="loginAction" class="onlyfun.caterpillar.LoginAction"> <property name="commandClass" 7 67
  • 68.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) value=”onlyfun.caterpillar.LoginForm”/> <property name="validator" ref="loginValidator"/> <property name="successView" value=”success”/> <property name="formView" value=”form”/> </bean> ... "validator" 至考參性屬 loginValidator 定設有要只,例實 "validator" , SimpleFormController 。它用使會就 用 使 以 可 您,時 證 驗 行 進 在 org.springframework.validation.Valida- 、 tionUtils 是像,法方態靜的便方些一有面上, rejectIfEmpty() r ejectIf- 。用使何如看件文 上線查查以可,等 EmptyOrWhitespace() API 義定 新 重 以 可 , 於對 , 面 方 一 另 AbstractWizardFormController vali- datePage() :如例,證驗行進來法方 ... protected void validatePage(Object command, Errors errors, int page) { (YourCommand) your = (YourCommand) command; switch(page) { case 1: validator.validateSome(your, errors); break; case 2: validator.validateOther(your, errors); break; .... } } ... 頁一行進每 Wizard的出送次該對針您讓,次一法方該叫呼會都,單表 ,證驗行進據數 " page" 與,數頁的單表出送次該示表數參 SimpleForm- 的 Controller Validator 動自會不 ,是的同不 A bstractWizardFormController 7 68
  • 69.
    Chapter 7 SpringWeb MVC 架框 方的應 對 行 進 料 資 的 面 頁 次 當 據 根 要 您 , 法 方 Validator validate() 的 行執 。行執來件物 個一由交證驗將,件物託委的上如取採常通,證驗法 Validator 7.3.2 使用 PropertyEditor 的它,說來別類子其及 BaseCommandController 於對 Command 件物 作實個一寫撰以可您 ,態型 是或態型本基受接要定一不並 String java. 轉 串字的 到 收 接 將 如 例 ,換轉行 進 中 當 在 ,別 類 的 beans.PropertyEditor User 。例實的別類 為換 :計設下如件物 Command 設假,說來例實個舉 PropertyEditorDemo SomeForm.java package onlyfun.caterpillar; public class SomeForm { private User user; public void setUser(User user) { this.user = user; } public User getUser() { return user; } } SomeForm 的現出中其而,表代件物的單表頁網為 User :計設下如別類 PropertyEditorDemo User.java package onlyfun.caterpillar; public class User { private String firstName; 7 6
  • 70.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) private String lastName; public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } } 收接 從而然,例實 的態型訂自個一收接將件物 Command User HTTP 轉做別類 個一 寫 撰 以 可 您 , 態 型 String 是值數參的到 UserPropertyEditor 義定新重並 承繼接直常通,換 java.beans.PropertyEditorSupport getAsText() :如例,法方 setAsText() 及 PropertyEditorDemo UserPropertyEditor.java package onlyfun.caterpillar; import java.beans.PropertyEditorSupport; public class UserPropertyEditor extends PropertyEditorSupport { public String getAsText() { Object o = this.getValue(); if(o == null || !(o instanceof User)) { return null; } User user = (User) o; String name = user.getFirstName() 7 7
  • 71.
    Chapter 7 SpringWeb MVC 架框 + "," + user.getLastName(); return name; } public void setAsText(String text) { String[] tokens = text.split(","); User user = new User(); user.setFirstName(tokens[0]); user.setLastName(tokens[1]); setValue(user); } } 行執會,時串字為換轉件物的定指從須必當 接而,法方 getAsText() 行執會,時件物的定指為換轉之將要數參到收 setAsText() 撰來著接,法方 : 的試測個一寫 Controller PropertyEditorDemo SomeFormController.java package onlyfun.caterpillar; import org.springframework.web.servlet. mvc.SimpleFormController; import org.springframework.web.servlet.*; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.springframework.web. bind.ServletRequestDataBinder; public class SomeFormController extends SimpleFormController { public SomeFormController() { setCommandClass(SomeForm.class); } protected ModelAndView onSubmit( Object command) throws Exception { SomeForm form = (SomeForm) command; 7 71
  • 72.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) Map model = new HashMap(); model.put("firstName", form.getUser().getFirstName()); model.put("lastName", form.getUser().getLastName()); return new ModelAndView(this.getSuccessView(), model); } protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); binder.registerCustomEditor( User.class, new UserPropertyEditor()); } } 了義定新重邊這到意注 initBinder() 用使中當在並,法方 Servlet- 的 RequestDataBinder registerCustomEditor()的訂自冊註法方 Property- Editor:容內的檔義定看看來, PropertyEditorDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.do">indexController</prop> <prop key="/someForm.do">someFormController</prop> </props> </property> </bean> 7 72
  • 73.
    Chapter 7 SpringWeb MVC 架框 <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="indexController" class="org.springframework.web.servlet. → mvc.ParameterizableViewController"> <property name="viewName" value="index"/> </bean> <bean id="someFormController" class="onlyfun.caterpillar.SomeFormController"> <property name="successView" value="hello"/> </bean> </beans> : 頁 網 試測個 一 有 寫 撰 設 假 在 現 PropertyEditorDemo index.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Form</title> </head> <body> <form name="someForm" action="/PropertyEditorDemo/someForm.do" method="POST"> 者用使<input type="text" name="user"/><br> <input type="submit" value="Submit"/> </form> </body> </html> 7 73
  • 74.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 由經會,後出送料資當,數參 了定設中位欄入輸在 " user" P ropertyEditor :寫撰下如頁網 的 果 結理處 現 呈 設 假 , 換 轉 的 hello.jsp PropertyEditorDemo hello.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>User Info</title> </head> <body> <h1>${firstName} - ${lastName}</h1> </body> </html> 在果如 index.jsp 入填 "Justin,Lin" :容內的下以示顯會果結則, 圖 7.17 PropertyEditorDemo 面畫果結的案專 7.3.3 檔案上傳 作實用使以可則,作動的傳上案檔行進要想果如 org.springframe- ,別類的面介 work.web.multipart.MultipartResolver S pring 供提 org. springframework.web.multipart.commons.CommonsMultipartResolver 與 org.springframework.web.multipart.cos.CosMultipartResolver 支別分, 援 Commands FileUpload 及 COS FileUpload 。 7 74
  • 75.
    Chapter 7 SpringWeb MVC 架框 個 一 了 計 設 您設假 , 子 例 的 際 實 個 舉 FileForm :別類 FileUploadDemo FileForm.java package onlyfun.caterpillar; public class FileForm { private String name; private byte[] contents; public void setName(String name) { this.name = name; } public void setContents(byte[] contents) { this.contents = contents; } public String getName() { return name; } public byte[] getContents() { return contents; } } FileForm 是態型性屬的傳上案檔受接中 byte 案檔的傳上者用使,列陣 由藉以可 org.springframework.web.multipart.support.ByteArrayMulti- partFileEditor為換轉 byte 給定設並列陣 FileForm 義定在須必這, Controller :如例,冊註時 7 7
  • 76.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) FileUploadDemo UploadController.java package onlyfun.caterpillar; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.BindException; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.multipart. support.ByteArrayMultipartFileEditor; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. mvc.SimpleFormController; public class UploadController extends SimpleFormController { private String path; public UploadController() { setCommandClass(FileForm.class); } protected ModelAndView onSubmit( HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { FileForm form = (FileForm) command; String storedPath = path + System.getProperty("file.separator") + form.getName(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( new FileOutputStream(storedPath)); bufferedOutputStream.write(form.getContents()); bufferedOutputStream.close(); 7 76
  • 77.
    Chapter 7 SpringWeb MVC 架框 return new ModelAndView(getSuccessView(), "filename", form.getName()); } protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); binder.registerCustomEditor( byte[].class, new ByteArrayMultipartFileEditor()); } public void setPath(String path) { this.path = path; } } 的傳上案檔用使要,下錄目的定指在存儲會後傳上案檔,定設的上以依 用使擇選以可,義 定的 入加中 檔義定在須 必,能功 MultipartResolver Com- 用使下以如 例, monsMultipartResolver 或 CosMultipartResolver Commons- MultipartResolver :義定 來 FileUploadDemo mvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.do">indexController</prop> <prop key="/upload.do">uploadController</prop> </props> 7 77
  • 78.
    Spring 2.0 良信林(冊手術技 – http://openhome.cc ) </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. view.InternalResourceViewResolver"> → <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="indexController" class="org.springframework.web.servlet. →mvc.ParameterizableViewController"> <property name="viewName" value="index"/> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart. commons.CommonsMultipartResolver"> → <property name="maxUploadSize" value="1000000"/> </bean> <bean id="uploadController" class="onlyfun.caterpillar.UploadController"> <property name="formView" value="form"/> <property name="successView" value="success"/> <property name="path" value="c:upload"/> </bean> </beans> 定設由藉,中檔義定在 為 性屬 UploadController 的 "path" "C:upload" , 在 存儲會 案 檔 的 後 傳 上 示 表 C:upload 個一計設著接,中之錄目 index.jsp : FileUploadDemo index.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> 7 78
  • 79.
    Chapter 7 SpringWeb MVC 架框 <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Upload Page</title> </head> <body> <form name="uploadForm" enctype="multipart/form-data" action="/FileUploadDemo/upload.do" method="POST"> 稱名案檔後載上 : <input name="name" type="text"/><br> 案檔擇選: <input name="contents" type="file"/><br> <input type="submit" value="Submit"/> </form> </body> </html> 檔的傳上要所擇選以可並,稱名案檔的後傳上定設以可中面頁個這在 s uccess.jsp :下如計設則 ,案 FileUploadDemo success.jsp <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>Upload Success</title> </head> <body> <h1>File: ${filename} upload successfully.</h1> </body> </html> 的依相到用使案專個這 Commands FileUpload 在要以所, lib 括包中錄目 commons-fileupload.jar 及以 commons-io.jar 檔 。案 7 7
  • 80.
    7 8 單簡為更現實的構架 MVC 讓 7.18 Spring 圖 J SF Struts 。等 、 是像,架框 的它其合整中 Web 在何如及以,案方 Spring 決 解的同 不 種 多 供 提 上 術 技 層 在 何 如 View 下一看來將節章個一下 Spring , 些這有 只 不 還 案 方 決 解 的 供 提 所 層 在 ,明說了作 應相及Web S pring API Controller 的種各與,構架要主的 Spring Web MVC 於對節章個一這 7.4 接下來的主題 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0