Spring Web Flow是Spring家族中的一位成員,他能簡化Web應用的開發。在Grails0.6中就集成了Spring Web Flow這一Web應用開發利器。下面通過一個實例向大家展示一下在Grails中如何方便的使用Spring Web Flow。
1,“grails create-app WebFlowDemo”,輸出如下:
D:\_DEV\grails_apps>grails create-app WebFlowDemo
Welcome to Grails 0.6 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails0.6
Base Directory: D:\_DEV\grails_apps
Environment set to development
Note: No plugin scripts found
Running script D:\D\MY_DEV\grails0.6\scripts\CreateApp.groovy
Overriding previous definition of reference to groovyJarSet
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\src
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFl
owDemo\src\java
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\src\groovy
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\controllers
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\services
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\domain
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\taglib
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\utils
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\views
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\views\layouts
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\i18n
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\conf
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\test
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\test\unit
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\test\integration
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\scripts
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\js
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\css
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\images
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\classes
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\META-INF
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\lib
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\conf\spring
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\grails-app\conf\hibernate
[propertyfile] Creating new property file:
D:\_DEV\grails_apps\WebFlowDemo\application.properties
[copy] Copying 2 files to
D:\_DEV\grails_apps\WebFlowDemo
[copy] Copying 2 files to
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF
[copy] Copying 5 files to
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\tld
[copy] Copying 131 files to
D:\_DEV\grails_apps\WebFlowDemo\web-app
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo\grails-app\conf
[copy] Copying 13 files to
D:\_DEV\grails_apps\WebFlowDemo\grails-app
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo\grails-app\conf\spring
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo
[propertyfile] Updating property file:
D:\_DEV\grails_apps\WebFlowDemo\application.properties
Created Grails Application at D:\_DEV\grails_apps/WebFlowDemo
D:\_DEV\grails_apps>
2,“cd WebFlowDemo”,進入工程目錄
3,“grails create-domain-class User”,創建一個域類User,輸出如下
D:\_DEV\grails_apps\WebFlowDemo>grails create-domain-class User
Welcome to Grails 0.6 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails0.6
Base Directory: D:\_DEV\grails_apps\WebFlowDemo
Environment set to development
Note: No plugin scripts found
Running script
D:\D\MY_DEV\grails0.6\scripts\CreateDomainClass.groovy
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo\grails-app\domain
Created for User
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo\test\integration
Created Tests for User
D:\_DEV\grails_apps\WebFlowDemo>
4,將grails-appdomainUser.groovy修改為如下內容:
class User implements Serializable {
String username
String password
}
5,“grails generate-all User”,生成所有與域類User相關的目錄和文件,輸出如下
D:\_DEV\grails_apps\WebFlowDemo>grails generate-all User
Welcome to Grails 0.6 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails0.6
Base Directory: D:\_DEV\grails_apps\WebFlowDemo
Environment set to development
Note: No plugin scripts found
Running script
D:\D\MY_DEV\grails0.6\scripts\GenerateAll.groovy
[mkdir] Created dir:
C:\Documents and Settings\Daniel\.grails\0.6\projects\WebFlowDemo\classes
Compiling 5 source files to
C:\Documents and Settings\Daniel\.grails\0.6\projects\WebFlowDemo\classes
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\grails-app\i18n
[copy] Copying 8 files to
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\grails-app\i18n
[copy] Copying 1 file to
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\spring
[copy] Copying 1 file to
C:\Documents and Settings\Daniel\.grails\0.6\projects\WebFlowDemo\classes
[copy] Copying 1 file to
C:\Documents and Settings\Daniel\.grails\0.6\projects\WebFlowDemo\classes
Generating views for domain class User
Generating controller for domain class User
Finished generation for domain class User
D:\_DEV\grails_apps\WebFlowDemo>
6,將grails-app\controllers\UserController.groovy修改為如下內容
class UserController {
def index = { redirect(action:list,params:params) }
// the delete, save and update actions only accept POST requests
def allowedMethods =
[delete: ' POST ' , save: ' POST ' , update: ' POST ' ]
def list = {
if ( ! params.max)params.max = 10
[ userList: User.list( params ) ]
}
def show = {
[ user : User.get( params.id ) ]
}
def delete = {
def user = User.get( params.id )
if (user) {
user.delete()
flash.message = " User ${params.id} deleted. "
redirect(action:list)
}
else {
flash.message =
" User not found with id ${params.id} "
redirect(action:list)
}
}
def edit = {
def user = User.get( params.id )
if ( ! user) {
flash.message =
" User not found with id ${params.id} "
redirect(action:list)
}
else {
return [ user : user ]
}
}
def update = {
def user = User.get( params.id )
if (user) {
user.properties = params
if (user.save()) {
flash.message =
" User ${params.id} updated. "
redirect(action:show,id:user.id)
}
else {
render(view: ' edit ' ,model:[user:user])
}
}
else {
flash.message =
" User not found with id ${params.id} "
redirect(action:edit,id:params.id)
}
}
def create = {
def user = new User()
user.properties = params
return [ ' user ' :user]
}
def save = {
def user = new User()
user.properties = params
if (user.save()) {
flash.message =
" User ${user.id} created. "
redirect(action:show,id:user.id)
}
else {
render(view: ' create ' ,model:[user:user])
}
}
def loginSystemFlow = {
login {
on( " login " ) {
if ( " daniel "
!= params.username || " 123 "
!= params.password) {
flash.message =
" username or password is invalid "
def user = new User()
user.properties = params
flash.user = user
return error ()
} else {
// 僅僅用來演示如何使用flow scope
flow.message =
"Welcome, ${params.username}"
}
}.to "ok"
on("register").to "showRegisterView"
}
ok()
showRegisterView()
}
}
on("login"){...}.to "ok"表示點擊login按鈕後所要去的頁面為ok,如果驗證失敗("daniel" != params.username || "123" != params.password),則利用內置的error(),使用戶返回login頁面;而on("register").to "showRegisterView"是類似的,不再累述。
7,在grails-app\views\user\目錄下新建一個名為“loginSystem”的子目錄,該名稱為UserController.groovy中的loginSystemFlow的“loginSystem”相對應。
8,在grails-app\views\user\loginSystem\目錄下新建login.gsp,ok.gsp,showRegisterView.gsp三個GSP文件(這三個文件的文件名與
def loginSystemFlow = {
login {
...
}
ok()
showRegisterView()
}
中粗體突顯的state名相對應,其中login為start state,而ok和showRegisterView為end state) ,並將其內容修改為:
login.gsp
< html >
< head >
< meta http-equiv ="Content-Type"
content ="text/html; charset=UTF-8" />
< meta name ="layout" content ="main" />
< title > Login Page </ title >
</ head >
< body >
< div class ="nav" >
< span class ="menuButton" >< a class ="home"
href ="${createLinkTo(dir:'')}" > Home </ a >
</ span >
</ div >
< div class ="body" >
< h1 >
Login Page
</ h1 >
< g:if test ="${message }" >
< div class ="message" >
${message }
</ div >
</ g:if >
< g:form action ="loginSystem" method ="post" >
< div class ="dialog" >
< table >
< tbody >
< tr class ='prop' >
< td valign ='top' class ='name' >
< label for ='username' >
Username:
</ label >
</ td >
< td valign ='top' class ='value
${hasErrors(bean:user,field:'username','errors')}' >
< input type ="text"
id ='username' name ='username'
value ="${user?
.username?.encodeAsHTML()}" />
</ td >
</ tr >
< tr class ='prop' >
< td valign ='top' class ='name' >
< label for ='password' >
Password:
</ label >
</ td >
< td valign ='top' class =
'value ${hasErrors(bean:user,field:'password','errors')}' >
< input type ="text"
id ='password' name ='password'
value ="${user?
.password?.encodeAsHTML()}" />
</ td >
</ tr >
</ tbody >
</ table >
</ div >
< div class ="buttons" >
< span class ="button" >< g:submitButton class ="save"
name ="login" value ="Login" ></ g:submitButton >
</ span >
</ div >
< g:link action ="loginSystem" event ="register" >
Register </ g:link >
</ g:form >
</ div >
</ body >
</ html >
ok.gsp
${message } < br />
< g:link action ="loginSystem" > back to login page </ g:link >
showRegisterView.gsp
This is a register page < br />
< g:link action ="loginSystem" > back to login page </ g:link >
9,“grails run-app”,啟動Grails應用,輸出如下
D:\_DEV\grails_apps\WebFlowDemo>grails run-app
Welcome to Grails 0.6 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails0.6
Base Directory: D:\_DEV\grails_apps\WebFlowDemo
Environment set to development
Note: No plugin scripts found
Running script D:\D\MY_DEV\grails0.6\scripts\RunApp.groovy
[mkdir] Created dir:
D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\lib
Compiling 1 source files to
C:\Documents and Settings\Daniel\.grails\0.6\projects\WebFlowDemo\classes
Running Grails application..
2007-09-08 00:12:24.443::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
2007-09-08 00:12:24.521::INFO: jetty-6.1.4
2007-09-08 00:12:26.425:/WebFlowDemo:
INFO: Set web app root system property: '@grails.project.key@'
= [D:\_DEV\grails_apps\WebFlowDemo\web-app\]
2007-09-08 00:12:26.425:/WebFlowDemo:
INFO: Initializing Log4J from
[D:\_DEV\grails_apps\WebFlowDemo\web-app\WEB-INF\classes\log4j.properties]
2007-09-08 00:12:26.472:/WebFlowDemo:
INFO: Loading Spring root WebApplicationContext
[9282] hibernate.ConfigurableLocalSessionFactoryBean
Building new Hibernate SessionFactory
[9922] mvc.GrailsUrlHandlerMapping Neither 'urlMap'
nor 'mappings' set on SimpleUrlHandlerMapping
[12750] commons.GrailsConfigUtils [GrailsContextLoader] Grails application loaded.
[12797] mvc.GrailsWebRequestFilter Initializing filter 'grailsWebRequest'
[12797] mvc.GrailsWebRequestFilter Filter 'grailsWebRequest' configured successfully
[12797] filter.UrlMappingsFilter Initializing filter 'urlMapping'
[12797] filter.UrlMappingsFilter Initializing filter 'urlMapping'
[12797] filter.UrlMappingsFilter Filter 'urlMapping' configured successfully
[12797] filter.UrlMappingsFilter Filter 'urlMapping' configured successfully
[12797] filter.GrailsReloadServletFilter Initializing filter 'reloadFilter'
[12797] filter.GrailsReloadServletFilter Filter 'reloadFilter' configured successfully
[12891] servlet.GrailsDispatcherServlet Initializing servlet 'grails'
[12954] servlet.GrailsDispatcherServlet
FrameworkServlet 'grails': initialization started
2007-09-08 00:12:36.562:/WebFlowDemo:
INFO: Loading WebApplicationContext for Spring FrameworkServlet 'grails'
[13485] servlet.GrailsDispatcherServlet
Using context class [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext]
for servlet 'grails'
[13485] servlet.GrailsDispatcherServlet
Using MultipartResolver [org.springframework.web.multipart
.commons.CommonsMultipartResolver@dd7404]
[13485] servlet.GrailsDispatcherServlet
Using LocaleResolver [org.springframework.web.servlet.i18n.SessionLocaleResolver@ebbf5c]
[13500] servlet.GrailsDispatcherServlet
Unable to locate ThemeResolver with name 'themeResolver':
using default [org.springframework.web.servlet.
theme.FixedThemeResolver@192c766]
[13516] servlet.GrailsDispatcherServlet
No HandlerAdapters found in servlet 'grails': using default
[13532] servlet.GrailsDispatcherServlet
Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator':
using default [org.springfra
mework.web.servlet.view.DefaultRequestToViewNameTranslator@a40575]
[13532] servlet.GrailsDispatcherServlet
Using MultipartResolver
[org.springframework.web.multipart.commons.CommonsMultipartResolver@dd7404]
[13532] servlet.GrailsDispatcherServlet
FrameworkServlet 'grails': initialization completed in 578 ms
[13532] servlet.GrailsDispatcherServlet Servlet 'grails' configured successfully
2007-09-08 00:12:37.374::INFO: Started [email protected]:8080
Server running. Browse to http://localhost:8080/WebFlowDemo
10,訪問http://localhost:8080/WebFlowDemo/user/loginSystem
11,輸入任意登錄信息,並按一下Login按鈕,我直接按Login按鈕 :)
12,輸入daniel和123,並按一下Login按鈕
Welcome, daniel
back to login page
13,點擊"back to login page"鏈接,在點擊login頁面上的Register鏈接
This is a register page
back to login page
一個最簡單的Spring Web Flow應用完成。