Spring Web Flow是Spring家族中的一位成員,他能簡化Web應(yīng)用的開發(fā)。在Grails0.6中就集成了Spring Web Flow這一Web應(yīng)用開發(fā)利器。下面通過一個(gè)實(shí)例向大家展示一下在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\WebFlowDemo\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”,進(jìn)入工程目錄
3,“grails create-domain-class User”,創(chuàng)建一個(gè)域類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-app\domain\User.groovy修改為如下內(nèi)容:
class
?User?
implements
?Serializable?{?
????String?username
????String?password
}
5,“grails generate-all User”,生成所有與域類User相關(guān)的目錄和文件,輸出如下
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修改為如下內(nèi)容
????????????
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"表示點(diǎn)擊login按鈕后所要去的頁面為ok,如果驗(yàn)證失敗("daniel"?!=?params.username?||?"123"?!=?params.password),則利用內(nèi)置的error(),使用戶返回login頁面;而on("register").to?"showRegisterView"是類似的,不再累述。
7,在grails-app\views\user\目錄下新建一個(gè)名為“loginSystem”的子目錄,該名稱為UserController.groovy中的loginSystemFlow的“l(fā)oginSystem”相對應(yīng)。
8,在grails-app\views\user\loginSystem\目錄下新建login.gsp,ok.gsp,showRegisterView.gsp三個(gè)GSP文件(這三個(gè)文件的文件名與
??? def?loginSystemFlow?=?{
????????login?{
??????????? ...
????????}
????????
????????ok()
????????
????????showRegisterView()
????}
中粗體突顯的state名相對應(yīng),其中l(wèi)ogin為start state,而ok和showRegisterView為end state)
,并將其內(nèi)容修改為:
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”,啟動(dòng)Grails應(yīng)用,輸出如下
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?SelectChannelConnector@0.0.0.0: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
page13,點(diǎn)擊"back to login page"鏈接,在點(diǎn)擊login頁面上的Register鏈接This is a register page
back to
login page一個(gè)最簡單的Spring Web Flow應(yīng)用完成。
最后告訴大家一個(gè)好消息,《Grails權(quán)威指南》最晚將在下個(gè)月出版,喜歡Grails的朋友到時(shí)可以買一本系統(tǒng)地學(xué)習(xí)一下Grails這個(gè)強(qiáng)大的框架,為自己今后的開發(fā)注入新的活力。關(guān)于此書的一些說明可以看一下《Grails權(quán)威指南》譯者序(草稿)
附:
朝花夕拾——Groovy & Grails
posted on 2007-09-08 00:39
山風(fēng)小子 閱讀(5969)
評(píng)論(3) 編輯 收藏 所屬分類:
Groovy & Grails