play初学者入门05Hello World示例教程文档格式.docx
- 文档编号:16545444
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:13
- 大小:540.44KB
play初学者入门05Hello World示例教程文档格式.docx
《play初学者入门05Hello World示例教程文档格式.docx》由会员分享,可在线阅读,更多相关《play初学者入门05Hello World示例教程文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
因为play使用UTF-8作为唯一的字符编码,所以所有位于以上目录的文本文件都必须使用UTF-8编码进行编写,开始书写代码前,请务必确定你的文本编辑器使用的是UTF-8编码。
如果你是一个老练的java开发者,你或许或奇怪编译后的.class文件去哪里了?
答案是在play里根本就不会存在.class文件。
Play根本不用.class文件,而是直接使用java源文件,play在运行中直接使用Eclipse编译器来编译java源代码并执行,结束运行后,这些存在于内存或临时目录的.class将被删除。
在开发过程中,这个特性非常重要。
首先是play会自动检测到java源代码的任何改动,并自动把修改后的源代码加载到运行时里。
其次是当java异常发生时,play将会创建友好的错误报告源代码中的错误位置,以帮助你及时排除问题。
运行应用程序
现在,我们就可以测试上面创建的应用程序了。
返回命令行,进入新创建的helloworld/目录,输入playrun命令,这时Play将加载这个应用程序,并启动一个端口为9000的web服务器。
打开浏览器,输入
http:
//localhost:
9000网址,此时会出现标准的欢迎页面,以告诉你应用程序已经成功创建。
接下来,让我们看看应用程序是如何显示这个欢迎页面的。
应用程序的主入口为
conf/routes
文件,这个文件定义了所有应用程序可以访问的URL。
打开这个文件,你就会看到第一条定义的路由如下:
GET/Application.index
这条路由告诉play,当web服务器接收到一个get请求的路径为/时,play必须调用Application.index
Java方法。
此处,Application.index是controllers.Application.index的简洁写法,因为在默认情况下,controllers包是直接导入了的。
我们在创建独立的java应用程序时,通常是使用下面的main方法作为单入口:
publicstaticvoidmain(String[]args){
...
}
一个Play应用程序可以有多个入口点,每个入口点都有一个对应的URL,我们把这些入口点方法称为action方法,这些action方法被定义在一个称为控制器的类里。
让我们看看
controllers.Application
控制器类是什么样的,打开helloworld/app/controllers/Application.java
源文件:
packagecontrollers;
importplay.mvc.*;
publicclassApplicationextendsController{
publicstaticvoidindex(){
render();
}
我们可以看到控制器类继承的是play.mvc.Controller类,这个类提供了所有和控制器相关的非常实用的方法比如我们在indexaction里使用的render()方法。
indexaction被定义成一个
publicstaticvoid
方法。
从这里,我们可以看到action方法是static的,这是因为控制器类永远不会被实例化。
同时,我们可以看到这些action被标记为public,这是为了让框架在响应URL请求时能够调用这些action。
另外,他们总是返回void。
默认的indexaction非常简单:
它调用render()方法来告诉play去渲染一个模板。
使用模板是最常用的用于生成http响应的方式(但不是唯一方式)。
模板都是些简单的文本文件,位于
/app/views
目录,因为我们并没有为render()指定模板,默认情况下,action方法将使用与其同名的模板
Application/index.html
让我们打开
helloworld/app/views/Application/index.html模板文件看看:
#{extends'
main.html'
/}
#{settitle:
'
Home'
#{welcome/}
模板内容看起来相当轻量,事实上,你看见的全是play标签。
play标签和jsp标签库非常接近。
#{welcome/}
标签生成了你在浏览器看到的默认欢迎页面。
#{extends/}
标签告诉play,这个模板继承于另外一个名叫main.html的模板。
模板继承是一个非常强大的概念,它允许通过重用通用部分的方式创建复杂的web页面。
helloworld/app/views/main.html
模板看看:
<
!
DOCTYPEhtml>
html>
<
head>
title>
#{get'
title'
/}<
/title>
metahttp-equiv="
Content-Type"
content="
text/html;
charset=utf-8"
/>
linkrel="
stylesheet"
type="
text/css"
media="
screen"
href="
@{'
/public/stylesheets/main.css'
}"
/>
shortcuticon"
image/png"
/public/images/favicon.png'
/head>
body>
#{doLayout/}
/body>
/html>
看到
#{doLayout/}
标签了吗?
这就是
Application/index.html
模板内容插入的地方。
创建窗体
下面我们将创建一个带有可以输入姓名的窗体的‘HelloWorld’应用程序。
编辑
helloworld/app/views/Application/index.html
模板文件:
formaction="
@{Application.sayHello()}"
method="
GET"
>
inputtype="
text"
name="
myName"
submit"
value="
Sayhello!
"
/form>
请注意:
在这里我们使用GET作为窗体提交方法,因为这个窗体很简单,不需要实现上传其他类型的数据。
我们使用
@{…}
记号来让play自动生成URL,以调用Application.sayHello
action。
现在,刷新一下浏览器看看。
哎,出错了!
这是因为你引用了一个不存在的action
Application.sayHello.OK,让我们在helloworld/app/controllers/Application.java文件里创建这个action:
render();
publicstaticvoidsayHello(StringmyName){
render(myName);
上面的代码里,我们在这个action方法的签名里声明了
myName
参数。
因此,当窗体提交时,http请求里的myName值将会自动填充到这个方法的同名签名里,并且调用render来显示模板。
既然我们在方法里把myName变量传递给了render()调用,那么myName也能被模板使用。
现在,如果你试着输入姓名并提交窗体,那么你会得到另外一个错误。
这个错误很明显,play将试着渲染与这个Action对应的默认模板sayHello.html,但遗憾的是这个默认的模板并不存在!
OK,接下来,我们为这个action创建其对应的默认模板
helloworld/app/views/Application/sayHello.html:
h1>
Hello${myName?
:
'
guest'
}!
/h1>
ahref="
@{Application.index()}"
Backtoform<
/a>
现在重新刷新页面看看,哈哈是不是可以正常工作了!
来看一下我们是如何在模板里使用Groovy的?
操作符的。
当myName变量没有输入任何值时,这个操作符用于切换使用myName变量的默认值,因此如果没有输入姓名的情况下提交窗体,将显示‘Helloguest’。
为程序提供一个更漂亮的URL
好,如果你仔细看一下提交的URL,你将看到和下面类似的URL:
9000/application/sayhello?
myName=guillaume
这并不友好,这是因为play使用了默认“匹配所有”路由的关系:
*/{controller}/{action}{controller}.{action}
我们可以通过为Application.sayHello
action指定一个路径,使URL更加漂亮。
编辑thehelloworld/conf/routes
文件,在第一行路由定义之后添加如下路由:
GET/helloApplication.sayHello
现在返回到窗体再次进行提交,这里使用的就是上面定义的URL范示了。
定制布局Customizingthelayout
迄今为止,我们使用的模板都是继承于同一个
main.html
模板,因此,我们可以很容易添加定制的布局。
方法是通过编辑helloworld/app/views/main.html
模板文件实现:
...
TheHelloworldapp.
hr/>
#{doLayout/}
OK,现在我们就为所有的页面添加了一个共用的头部:
添加验证
我们可以为窗体添加一点验证,以明确窗体的name域是必须填写的。
在这里,我们可以用play的验证validation框架来完成这件事。
helloworld/app/controllers/Application.java
控制器里的
sayHello
action:
publicstaticvoidsayHello(@RequiredStringmyName){
if(validation.hasErrors()){
flash.error("
Oops,pleaseenteryourname!
);
index();
别忘记了导入
play.data.validation.*
包,以便我们用使用@Required
注释。
这时,Play将自动检测窗体的myName域是否已经填写,如果没有填写,play将添加一个error对象到errors作用域里。
在这里,如果没有填写,我们将添加一条消息到flash作用域,并且直接重定向到index
flash作用域仅在action重定向期间有效。
接下来,我们需要修改helloworld/app/views/Application/index.html模板文件,以便于在有任何错误发生时及时显示错误消息。
#{ifflash.error}
pstyle="
color:
#c00"
${flash.error}
/p>
#{/if}
哈哈,窗体输入域验证可以正常工作了。
书写自动测试单元
接下来,我们将完成应用程序的测试代码书写。
因为在上面这个示例里并没有java逻辑供测试,因此,我们只需测试web应用程序自身就行,所以我们将书写一个Selenium测试。
首先,你需要以测试模式运行应用程序,在这里,我们先停止应用程序,再用下面的命令重新启动:
$playtest
playtest
命令和
playrun乎完全相同,除了其会自动加载测试运行时模板以允许你从浏览器直接运行单元测试外。
.
9000/@tests
网址就可以看到testrunner。
试着选择所有默认的测试并运行,所有的结果应该是绿色的,但要注意,这些默认测试其实并没有真正测试任何代码。
一个selenium测试通常为一个html文件,selenium必须的HTML语法有点单调(使用HTMLtable元素来格式化数据),好消息是play会使用模板引擎帮助你自动生成它所需要的模板,并提供一些用于selenium脚本的简单标签。
新创建应用程序的默认单元测试已经包含了一个seleniumtest,打开helloworld/test/Application.test.html
文件:
*{Youcanuseplainseleniumcommandusingtheseleniumtag}*
#{selenium}
//Openthehomepage,andcheckthatnoerroroccurred
open('
/'
)
assertNotTitle('
Applicationerror'
#{/selenium}
默认情况下,这个测试应该会正常运行,它的功能仅仅是打开了home页并检测页面内容是否包含有‘Applicationerror’文本。
现在,让我们为自己的应用程序写一个测试,编辑上面的这个文件:
//CheckthatitistheHelloWorldapplication
assertTextPresent('
TheHelloworldapp.'
//Submittheform
clickAndWait('
css=input[type=submit]'
//Checktheerror
//Typethenameandsubmit
type('
css=input[type=text]'
'
bob'
//Checktheresult
Hellobob!
//Checkthebacklink
link=Backtoform'
//Homepage?
assertTextNotPresent('
这样,我们就能完整测试helloworld应用程序了,保存上述代码,在浏览器的testrunner里选择test,单击‘Start’。
Ok,所有测试都应该是绿色的。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- play初学者入门05Hello World示例教程 play 初学者 入门 05 Hello World 示例 教程