那麼View和Controller之間要怎麼溝通呢?在這裡以一個簡單的例子實作來展示一些在Spring中View和Controller之間溝通的方式。
例子要實做的內容為,使用者一開始會進入一個表單輸入頁面,可以輸入名字及選擇稱謂(先生或小姐),按下送出按鈕後,會引導到招呼畫面,其中招呼內容包含輸入的名字及稱謂,而如果名字為雨果及稱謂為先生的話,招呼畫面的內容會稍有不同。
首先先來看專案的配置:
其中包括:
- dispatcher-servlet.xml:Spring的dispatcherServlet設定檔。
- FormView.html:一開始的表單輸入頁面。
- FormCheckResultView.jsp:招呼畫面。
- FormController.java:接收及轉送參數的Controller。
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>
dispatcher-servlet.xml:
<?xml version='1.0' encoding='UTF-8' ?> <!-- was: <?xml version="1.0" encoding="UTF-8"?> --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <mvc:resources location="/" mapping="/**"/> <context:component-scan base-package="/Controller" /> <!-- 掃描package中有用注解的類別 --> <mvc:annotation-driven /> <!-- 使用注解驅動 --> </beans>
在FormView.html中,只是簡單的設置了表單、選項及按鈕:
FormView.html:
<!DOCTYPE html> <html> <head> <title>填表輸入頁面</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div>填表輸入頁面</div> <form action="FormController.do"> 輸入名字:<input type="text" name="name" /> <br/> 先生或小姐: <select name="sex"> <option value="先生">先生</option> <option value="小姐">小姐</option> </select> <br/> <input type="submit" value="確定送出" /> </form> </body> </html>
主要的重頭戲在FormController.java中,可以看到如果忽略Spring的Annotation的話,就只是一個普通的POJO而已,其中可以看到所展示的兩種從FormView.html中得到表單參數、及將參數送往FormResultCheckView.jsp的方式,還有如何判斷參數狀況來使用不同的Method處理的方式:
FormController.java:
package Controller; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller public class FormController { //一開始無任何參數,直接返回表單輸入頁面 @RequestMapping(value = {"/", "FormController.do"}) public String returnToFormView() { return "/FormView.html"; } //第一種Controller傳參數給View的方式, //使用回傳ModelAndView及ModelAndView.addObject()放參數進去給View //如果有名為name的參數,執行toResultViewForNormal() @RequestMapping(value = "FormController.do", params = {"name"}) public ModelAndView toResultViewForNormal(@RequestParam("name") String name, @RequestParam("sex") String sex) { ModelAndView modelAndView = new ModelAndView("/FormCheckResultView.jsp"); modelAndView.addObject("name", name); modelAndView.addObject("sex", sex); return modelAndView; } //第二種Controller傳參數給View的方式, //使用回傳String及map.out()放參數進去給View //如果有名為name及sex的參數,並且name的值為"雨果"、sex的值為"先生",則執行checkAndToResultView() @RequestMapping(value = "FormController.do", params = {"name=雨果","sex=先生"}) public String toResultViewForGreatHugo(@RequestParam("name") String name, @RequestParam("sex") String sex, Map<String, Object> map) { map.put("name", name); map.put("sex", sex); map.put("greeting", "偉大的"); //多傳一個"greeting"參數給View return "/FormCheckResultView.jsp"; } }
FormCheckResultView.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>歡迎頁面</title> </head> <body> <h1>您好, ${greeting} ${name} ${sex} </body> </html>成品如下,如果輸入了名字並選擇先生或小姐的稱謂時,會被引導至招呼畫面:
而如果輸入的名字是 "雨果" 且稱謂為 "先生" 時,招呼畫面的顯示會有所不同:
附上原始碼:
SpringViewContollerCommunication.7z
參考資料:
- Spring MVC and Thymeleaf: how to access data from templates
- SpringMVC常用註解實例詳解2:@ModelAttribute GOOD
- Spring 教學(2) - 關於@RequestMapping
您好
回覆刪除照您上面的方法做,我這邊出現這個錯誤,
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringSample/FormController.do]
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /FormController.do
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Did not find handler method for [/FormController.do]
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Matching patterns for request [/FormController.do] are [/**]
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - URI Template variables for request [/FormController.do] are {}
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Mapping [/FormController.do] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@193949b]]] and 1 interceptor
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - Last-Modified value for [/SpringSample/FormController.do] is: -1
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
18:15:32.439 [http-nio-8080-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
可以請教您如何解決嗎?
您可以下載我的原始碼,解壓縮後用Netbeans開Project測試看看,應該是可以成功的,可以跟你的專案比較看看。
刪除因為沒看到你的完整專案不能確定,不過我看了你的錯誤訊息,猜測應該是url-pattern沒有設好或目錄結構跟我不同等,造成Srping的dispatcher servlet找不到你的url路徑(/SpringSample/FormController.do)應該要對應的FormController.class中的method。記得註意檔案放置的位置及xml配置檔的內容
請問您的web.xml,為什麼有這個錯誤:cvc-complex-type.2.3: Element 'context-param' cannot have character [children], because the type's content type is element-only.可是整個專案還是可以執行?? 可以請教你為什麼會這樣嗎???
回覆刪除我沒有看到您所說的錯誤訊息,我猜測您是否是使用Eclipse?或是直接複製貼上我網頁上web.xml的內容?如果是的話建意可先貼到記事本上,再貼到您要的地方,以避免複製了一些xml不合法的字符。或是您可以使用包住有xml不合法字符的內容。或是檢查xml內容,是否有不正確的字符、空白等內容。
刪除