02 Hello World

建立HelloWorld專案:

終端機鍵入:(建立專案-->設定IDE-->匯入IDE-->啟動測試)
# play new helloworld
# play eclipsify helloworld
....import project to Eclipse IDE....
# play run helloworld


conf/routes檔案為應用程式主要進入點(The main entry point),此檔案定義了所有應用程式的訪問網址。

# Home page
GET     /                                       Application.index

當Web伺服器接收到根(/)目錄的GET請求時,必須調用Application.index中的Java方法。而Application.index是一個快速調用controllers.Application.index的方式,因為controllers package是隱含物件。

來看看如何運用controllers.Application控制器的模式,位於/app/controllers/Application.java source file:

package controllers;

import play.mvc.*;

public class Application extends Controller {

    public static void index() {
        render();
    }
}

play.mvc.Controller class提供了所有有用的控制器方法,以render()方法則使用了索引操作。

The index action提供了public static void方法定義,所以,控制器類別(the controller classes)從未被實例化,而總是返回void。、


預設的索引操作(index action)很簡單,它調用render()方法告註Play來呈現出一個模板(Template)。使用模板(Template)是常見的方式之一來生成HTTP Response(但不是唯一的一個)。

模板(Template)是簡易文件檔案放置於 /app/views 目錄下。因為沒有指定模板(Template),所以預設使用Application/index.html

查看模板(Template),開啟/app/views/Application/index.html file:

#{extends 'main.html' /}
#{set title:'Home' /}

#{welcome /}

事實上,你所看到的是Play Tag,它非常接近JSP標籤庫。而 #{welcome /}標籤則是在瀏覽器所看到的歡迎訊息。

#{extends /} tags是告訴Play該模板(Template)繼承了另一個模板稱main.html。模板繼承(Template inheritance)是一個強大的概念,它允許創建複雜的網頁,通過重複使用的共同部分。

接下來,開啟/app/views/main.html template

<!DOCTYPE html>

<html>
    <head>
        <title>#{get 'title' /}</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/main.css'}">
        #{get 'moreStyles' /}
        <link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}">
        <script src="@{'/public/javascripts/jquery-1.4.2.min.js'}" type="text/javascript" charset="utf-8"></script>
        #{get 'moreScripts' /}
    </head>
    <body>
        #{doLayout /}
    </body>
</html>

#{doLayout /} tag是指Application/index.html的內容將被插入。

建立表單

開始建立HelloWorld Form 以便輸入字串,編輯/app/views/Application/index.html template:

#{extends 'main.html' /}

#{set title:'Home' /}

<form action="@{Application.sayHello()}" method="GET">

    <input type="text" name="myName" />

    <input type="submit" value="Say hello!" />

</form>


使用@{…}標記,要求Play自動生成URL可以調用 Application.sayHello action。現在刷新Home Page:



此錯誤訊息是因為此Application.sayHello action參考不存在,因此,創建一個檔案於/app/controllers/Application.java

package controllers;
import play.mvc.*;
public class Application extends Controller {
    public static void index() {
        render();
    }
    public static void sayHello(String myName) {
        render(myName);
    }
}

宣佈了myName參數於Action方法上,就會自動填充HTTP MyName的參數值,並提交表單。我們呼叫渲染(render)只顯示一個模板(Template),因為我們通過MyName的變數至render()上。



現在,如果嚐試輸入你的名字,並提交表單,會得到一個錯誤訊息:




此錯誤訊息是Play試圖呈現預設模板(default template)在這次的action method上,但是,它並不存在。讓我們創建一個檔案在/app/views/Application/sayHello.html上,並刷新瀏覽器:

#{extends 'main.html' /}
#{set title:'Home' /}
<h1>Hello ${myName ?: 'guest'}!</h1>
<a href="@{Application.index()}">Back to form</a>




試著不輸入字串並提交表單,它會顯示Hello guest

提供更好的URL

如果你看看提交後的URL,你會看到類似像:

http://localhost:9000/application/sayhello?myName=guillaume

這樣不是很好。這是因為Play used the default ‘catch all’ route

*       /{controller}/{action}                  {controller}.{action}

為了通過更好的URL,我們可以自定義路徑為Application.sayHello action。所以,可以編輯/conf/routes檔案並增加指定路徑在第一組路徑之後。

GET     /hello                                  Application.sayHello

再次回到表單並提交再次檢查它使用新的URL模式。

自定義佈局

藉由兩組模板,應用程式使用至今繼承自同main.html template,你可以方便增加自定義佈局。編輯/app/views/main.html file:

...
<body>
    The Hello world app.
    <hr/>
    #{doLayout /}
</body>
...

現在這兩個頁面都有一個共同的header

添加驗證

接下來將增加驗證形式在名稱欄位上。我們可以用Play validation framework去做。
編輯/app/controllers/Application.java controllersayHello action

...
public static void sayHello(@Required String myName) {
    if(validation.hasErrors()) {
        flash.error("Oops, please enter your name!");
        index();
    }
    render(myName);
}
...

記得import play.data.validation.*包來獲取@Required annotation。Play將自動檢查myName欄位是否填入值或增加一個error object傳遞至errors scope。其次,如有任何錯誤,則增加一個訊息至 flash scope以及重新定向(redirect)至index action。

The flash scope允許重新定向(redirection)時保留訊息。

如有錯誤訊息的話,則編輯/app/views/Application/index.html,並啟動瀏覽器:

#{extends 'main.html' /}
#{set title:'Home' /}
#{if flash.error}
    <p style="color:#c00">
        ${flash.error}
    </p>
#{/if}
<form action="@{Application.sayHello()}" method="GET">
    <input type="text" name="myName" /> 
    <input type="submit" value="Say hello!" />
</form>






寫一組自動測試套件

我們將完成一個測試應用程式,由於沒有Java的邏輯測試,我們需要測試Web應用程式本身。因此,將撰寫一個Selenium test。

首先,你需要運行你的應用程式在測試模式(test mode)下,停止應用程式並重新啟動於測試命令(test command)

play test

Play test command幾乎與Play run command 相同,但它加載的測試運行模組,允許瀏覽器直接運行測試套件。
開啟瀏覽器輸入網址http://localhost:9000/@tests看到測試運行。盡量選擇預設的測試並運行他們都應該是綠色的,但這些預設測試沒有真正的測試任何東西。









Comments