欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      play手把手教你創(chuàng)建一個博客項目-08.添加身份認證

      時間:2019-05-15 00:38:46下載本文作者:會員上傳
      簡介:寫寫幫文庫小編為你整理了多篇相關的《play手把手教你創(chuàng)建一個博客項目-08.添加身份認證》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《play手把手教你創(chuàng)建一個博客項目-08.添加身份認證》。

      第一篇:play手把手教你創(chuàng)建一個博客項目-08.添加身份認證

      08.添加身份認證

      在上一節(jié)是,我們?yōu)閼贸绦蛱砑恿斯芾韰^(qū)域(administration area)功能,現(xiàn)在我們將在這些管理區(qū)域中插入一些身份認證功能。幸運的是,play已經(jīng)為這個功能準備了一個模塊,這個模塊叫Secure(安全)。

      在程序里允許使用Secure模塊

      在yabe/conf/application.conf文件里允許使用Secure模塊,并重啟程序: # Import the secure module module.secure=${play.path}/modules/secure 重啟后,play應用在控制臺顯示模塊已經(jīng)成功啟動的相關信息。

      Secure模塊帶有一系列默認的路由,需要在yabe/conf/routes里引入(或定義自己的路由也行): # Import Secure routes * / module:secure 保護admin(此處指需要身份認證的)控制器

      安全模塊提供了一個controllers.Secure控制器,它聲明了所有可能用到的攔截器。當然,我們可以以繼承這個控制器的方法獲得其攔截器,但是java只允許單繼承,這就導致了一些問題。

      為了避免單繼承帶來的限制,我們可以用@With來注釋admin控制器,以告訴play去調(diào)用相應的攔截器:

      package controllers;

      import play.*;import play.mvc.*;

      @With(Secure.class)public class Posts extends CRUD { } 同樣用于Comments, Users和Tags控制器。

      Now if you try to access any admin action, you should get a log-in page: 事實上,現(xiàn)在你就可以試著輸入任意username/password對看看,它其實并沒有對身份進行認證。

      定制身份認證處理

      應用程序必須提供一個controllers.Secure.Security實例來定制身份認證處理。通過繼承這個類來創(chuàng)建我們自己版本的Secure類,我們可以指定如何對用戶身份進行認證。

      創(chuàng)建yabe/app/controllers/Security.java文件,重寫authenticate()方法: package controllers;

      import models.*;

      public class Security extends Secure.Security {

      static boolean authenticate(String username, String password){ return true;} } 既然我們已經(jīng)擁有了User對象,那么就非常容易實現(xiàn)這個方法: static boolean authenticate(String username, String password){ return User.connect(username, password)!= null;} 現(xiàn)在打開http://localhost:9000/logout進行登錄嘗試,用戶名和密碼在initial-data.yml文件里定義,比如bob@gmail.com/secret。

      重構(gòu)管理區(qū)域(administration area)

      我們之前已經(jīng)使用CRUD模塊來實現(xiàn)管理區(qū)域,但是這個管理區(qū)域仍然沒有集成到博客UI里,接下來我們將在一個新的管理區(qū)域上開始工作。這個新的管理區(qū)域允許每個作者訪問他自己的博客。而超級用戶則繼續(xù)使用完整功能的管理區(qū)域。

      接下來,讓我們?yōu)楣芾聿糠謩?chuàng)建一個新Admin控制器: package controllers;

      import play.*;import play.mvc.*;

      import java.util.*;

      import models.*;

      @With(Secure.class)public class Admin extends Controller {

      @Before static void setConnectedUser(){ if(Security.isConnected()){ User user = User.find(“byEmail”, Security.connected()).first();renderArgs.put(“user”, user.fullname);} }

      public static void index(){ render();} } 重構(gòu)路由定義yabe/conf/routes: # Administration GET /admin/? Admin.index * /admin module:crud 請注意路由的順序,第一行就匹配了的http請求相應的action會率先使用,同時忽略在其之下的路由配置。也就是說Admin控制器必須位于第二行之上,第二條路由將匹配所有其他的/admin請求,用于調(diào)用CRUD模塊頁面,否則/admin/將映射到CRUD.index而不是Admin.index。

      現(xiàn)在把yabe/app/views/main.html模塊里的 ‘Log in to write something’文本修改到Admin.index控制器action:

      最后一件事就是為yabe/app/views/Admin/index.html模板文件完成所有的填充工作,讓我們從簡單的開始: Welcome ${user}!現(xiàn)在回到主頁,單擊 ‘Log in to write something’鏈接就回進入樣的管理區(qū)域頁面: 非常好!但是既然我們已經(jīng)有幾個管理區(qū)域的頁面,那么,我們就應該有一個超級模板以重用代碼,讓我們創(chuàng)建一個yabe/app/views/admin.html模板: Administration

      #{get 'moreStyles' /}

      yabe.administration

      第二篇:play手把手教你創(chuàng)建一個博客項目-03.構(gòu)建第一個頁面

      03.構(gòu)建第一個頁面

      之前,我們已經(jīng)編寫好了數(shù)據(jù)模型,是時候為應用程序創(chuàng)建第一個頁面了。這個頁面只顯示當前發(fā)表的博文完整內(nèi)容,同時顯示之前發(fā)表的博文列表。下面是該頁面結(jié)構(gòu)示意圖:

      在啟動時加載默認數(shù)據(jù)

      事實上,在編寫第一個頁面之前,我們還需要做一些工作。在一個沒有任何測試數(shù)據(jù)的頁面上進行工作并不太好,你甚至不能進行任何測試。

      為博客程序注入測試數(shù)據(jù)的一條途徑就是在應用程序啟動時加載一個固定文件。為了實現(xiàn)這個目的,我們將創(chuàng)建一個引導任務(Bootstrap Job)。一個play job 任務就是一在沒有任何http請求的情況下執(zhí)行一些特定工作,比如在應用程序啟動時或指定時間間隔時使用CRON任務。

      接下來,讓我們創(chuàng)建/yabe/app/Bootstrap.java job文件,使用Fixtures加載一系列默認數(shù)據(jù):

      import play.*;import play.jobs.*;import play.test.*;

      import models.*;

      @OnApplicationStart public class Bootstrap extends Job {

      public void doJob(){ // 檢查數(shù)據(jù)庫是否為空 if(User.count()== 0){ Fixtures.loadModels(“initial-data.yml”);} } } 在這里,我們使用@OnApplicationStart來注釋這個Job,用于告訴play我們打算在應用程序啟動時同步運行這個任務。

      事實上,在DEV和PROD模式下,這個任務的運行情況有所不同。在DEV模式下,play會等待第一個請求達到時才運行任務。因此這個任務會在第一個請求到達時才同步執(zhí)行,也就是說,如果這個任務失敗,你會在瀏覽器里看到錯誤消息。在PROD模式里,這個任務將會在應用程序啟動時就執(zhí)行(與play run命令同步),以防止應用程序在啟動時發(fā)生錯誤。

      你必須在yabe/conf/下創(chuàng)建一個initial-data.yml文件。當然,你也可以重用我們之前在data.yml里定義的內(nèi)容。

      博客主頁

      這次,我們將真正開始編寫主頁代碼。

      還記得程序的第一個頁面是如何顯示的嗎?首先是在routes文件里指定/ URL 將調(diào)用controllers.Application.index()action方法,然后這個index()調(diào)用render()方法渲染/yabe/app/views/Application/index.html模板。我們將保留這些組件,但是我們會在其中添加代碼來加載博文列表并顯示。打開/yabe/app/controllers/Application.java控制器并修改index()action來加載博文列表:

      package controllers;

      import java.util.*;

      import play.*;import play.mvc.*;

      import models.*;

      public class Application extends Controller {

      public static void index(){ Post frontPost = Post.find(“order by postedAt desc”).first();List

      olderPosts = Post.find(“order by postedAt desc”).from(1).fetch(10);render(frontPost, olderPosts);} } 看到我們是如何向render方法傳遞對象的嗎?通過這種方式,我們就可以在模板里使用相同的名稱來訪問這些對象了。在上面的代碼里,我們在模板里就可以直接使用變量frontPost和olderPosts。

      打開/yabe/app/views/Application/index.html并修改,用于顯示這些對象: #{extends 'main.html' /} #{set title:'Home' /}

      #{if frontPost}

      ${frontPost.title}

      by ${frontPost.author.fullname} ${frontPost.postedAt.format('MMM dd')} ?|? ${frontPost.comments.size()?: 'no'} comment${frontPost.comments.size().pluralize()} #{if frontPost.comments} , latest by ${frontPost.comments[-1].author} #{/if}

      第三篇:play手把手教你創(chuàng)建一個博客項目-09.創(chuàng)建定制編輯區(qū)域

      09.創(chuàng)建定制編輯區(qū)域

      在之前的教程中,我們已經(jīng)創(chuàng)建一個管理區(qū)域(administration area),并準備好了‘My posts’部分。這個頁面將為每位作者提供一個屬于他自己博文的列表,并且可以對這些博文進行編輯或創(chuàng)建新的博文。

      我們可以重用CRUD模塊作為這個頁面的基礎,但在這里,我們將以此為基礎(scratch,起跑線,基礎)創(chuàng)建一些東西,我們需要在這些屏幕里提供許多個性化的東西。

      從用戶博文列表開始

      在這里,我們只需得到并顯示當前登錄用戶的博文。非常簡單,讓我們開始增強Admin.index action的功能: public static void index(){ String user = Security.connected();List

      posts = Post.find(“author.email”, user).fetch();render(posts);} 并且完成yabe/app/views/Admin/index.html模板: #{extends 'admin.html' /}

      Welcome ${user}, you have written ${posts.size()?: 'no'} ${posts.pluralize('post', 'posts')} so far

      #{list items:posts, as:'post'}

      ${post.title}

      #{/list}

      + write a new post

      第一個屏幕就準備好了: 接著寫‘寫一篇新博文’頁面

      我們將創(chuàng)建一個窗體來實現(xiàn)創(chuàng)建一篇新博文。通常情況下,在窗體操作時你需要兩個actions:一個用于顯示窗體,另一個用于處理窗體提交的信息。讓我們創(chuàng)建這個新的Admin.form和Admin.save actions,以用于顯示和處理窗體提交信息:

      在abe/conf/routes里添加如下路由:

      GET /admin/new Admin.form POST /admin/new Admin.save 接著在Admin.java控制器里添加form()和save()actions: public static void form(){ render();}

      public static void save(){ // Not implemented yet } 接著,你就必須創(chuàng)建yabe/app/views/Admin/form.html模板:

      #{extends 'admin.html' /}

      Write, a new post

      #{form @save()}

      #{ifErrors}

      Please correct these errors.

      #{/ifErrors}

      #{field 'title'} #{error 'post.title' /} #{/field}

      #{field 'content'} #{error 'post.content' /} #{/field}

      #{field 'tags'} #{/field}

      #{/form} 最后編輯yabe/app/views/Admin/index.html模板來鏈接到 Write a new post 按鈕到這個窗體:

      ...

      + write a new post

      ...檢測一下結(jié)果: 接下來,我們必須完成Admin.save action,以用于處理當前窗體提交的數(shù)據(jù)。action將創(chuàng)建一個新的Post對象,把tag(特征)列表轉(zhuǎn)換到真實的Tag對象集合,驗證所有的字段并存儲他們。如果有任何問題發(fā)生,那么還能夠重新顯示窗體,并標出錯誤位置:

      public static void save(String title, String content, String tags){ // Create post User author = User.find(“byEmail”, Security.connected()).first();Post post = new Post(author, title, content);// Set tags list for(String tag : tags.split(“s+”)){ if(tag.trim().length()> 0){ post.tags.add(Tag.findOrCreateByName(tag));} } // Validate validation.valid(post);if(validation.hasErrors()){ render(“@form”, post);} // Save post.save();index();} 在這里,我們使用render(“@form”)作為render(“Admin/form.html”)的快捷方式,它只告訴play去使用窗體action的默認模板。測試下看看!

      為正在編輯的Posts重用這些填充數(shù)據(jù)

      我們已經(jīng)定義了HTML窗體并且讓Java action能夠創(chuàng)建一個新的博客Post,但是我們同時也需要允許編輯存在的博文,因此我們可以很容易地重用相同的代碼,使我們在編輯現(xiàn)有博文時的工作量盡量減少: 首先我們需要讓Admin.form找回存在的Post: public static void form(Long id){ if(id!= null){ Post post = Post.findById(id);render(post);} render();} 正如你所看到的一樣,我們使之成為可選項(通過id!=null),因此當id參數(shù)已經(jīng)填值后,同樣的action將用于找回存在的博文。因此,我們現(xiàn)在可以把主屏幕的博文列表鏈接到編輯窗體了。編輯yabe/app/views/Admin/index.html模板:

      #{extends 'admin.html' /}

      Welcome ${user}, you have written ${posts.size()?: 'no'} ${posts.pluralize('post', 'posts')} so far

      #{list items:posts, as:'post'}

      ${post.title}

      #{/list}

      + write a new post

      非常好,很容易就實現(xiàn)了,但這里還有一個小問題。如果你看一下通過Router為這些鏈接生成的真實的URL,你就會發(fā)現(xiàn)如下樣式的URL: /admin/new?id=3 它們能正常工作,但是并不太漂亮。OK,讓我們對其進行修改,如果id參數(shù)提交上來,我們將使用一個不同的URL范示,路由定義如下: GET /admin/myPosts/{id} Admin.form GET /admin/new Admin.form 正如你看到的一樣,我們在舊的路由之前定義了這些路由,因此它們具有更好的優(yōu)先級。這也就是說,如果一個id參數(shù)被提交,play將率先使用這個URL范示,如果沒有提交id參數(shù),那么play將繼續(xù)使用舊的路由。刷新My posts頁面看看更賈漂亮的URL鏈接效果。

      接下來我們需要修改yabe/app/views/Admin/form.html模板,使其更好: #{extends 'admin.html' /}

      #{ifnot post?.id}

      Write, a new post

      #{/ifnot} #{else}

      Edit, this post

      #{/else}

      #{form @save(post?.id)}

      #{ifErrors}

      Please correct these errors.

      #{/ifErrors}

      #{field 'title'} #{error 'post.title' /} #{/field}

      #{field 'content'} #{error 'post.title' /} #{/field}

      #{field 'tags'} #{/field}

      #{/form} 正如你看到的一樣,我們已經(jīng)更新窗體目的action,以方便添加博文ID作為第一個action參數(shù)。因此當博文擁有一個id字段集時(意思是博文在系統(tǒng)里已經(jīng)存在),窗體將發(fā)送到Admin.save action進行處理。接下來我們可以修改save()方法來處理創(chuàng)建與編輯兩種情況:

      public static void save(Long id, String title, String content, String tags){ Post post;if(id == null){ // Create post User author = User.find(“byEmail”, Security.connected()).first();post = new Post(author, title, content);} else { // Retrieve post post = Post.findById(id);// Edit post.title = title;post.content = content;post.tags.clear();} // Set tags list for(String tag : tags.split(“s+”)){ if(tag.trim().length()> 0){ post.tags.add(Tag.findOrCreateByName(tag));} } // Validate validation.valid(post);if(validation.hasErrors()){ render(“@form”, post);} // Save post.save();index();} 使用和之前同樣的技巧,讓URL更加完美,如果id參數(shù)存在,我們就使用優(yōu)先路由:

      POST /admin/myPosts/{id} Admin.save POST /admin/new Admin.save 工作全部完成!現(xiàn)在我們使用同一樣action就實現(xiàn)了創(chuàng)建新博文與編輯舊博文的功能,同時完成了管理區(qū)域administration area)的編程工作!

      第四篇:play手把手教你創(chuàng)建一個博客項目-04.顯示并發(fā)表評論

      04.顯示并發(fā)表評論

      博客的主頁已經(jīng)搞定,接下來,我們將編寫博文的詳細內(nèi)容頁面。這個頁面將顯示當前博文的所有評論,頁面還將包括一個用于發(fā)表新評論的窗體。

      創(chuàng)建 ‘show’ action

      為了顯示博文的詳細頁面,我們需要在Application控制器里創(chuàng)建一個新的action方法,這個新的action叫做show(): public static void show(Long id){ Post post = Post.findById(id);render(post);} 你可以看到,這個action非常簡單。我們在方法簽名里聲明了一個Long類型的id參數(shù)用于自動從http請求的id變量里得到id值。這個參數(shù)會從HTTP的請求字符串、URL路徑或窗體里獲得

      如果我們試著從http請求里傳遞一個錯誤的id值時,id變量值將為null,這時play將自動添加一個驗證錯誤秋errors容器(變量)里。

      這個action將用/yabe/app/views/Application/show.html模板進行顯示: #{extends 'main.html' /} #{set title:post.title /}

      #{display post:post, as:'full' /} 由于我們在之前已經(jīng)編寫了display標簽,因此在這個頁面的編碼就非常簡單了。

      為詳細頁面添加鏈接

      在display標簽里,我們讓所有的鏈接為空(使用#)。是時候讓這些鏈接指向Application.show action了。在play里,你可以很容易在一個模板里使用@{...}注釋構(gòu)建鏈接,這個語法使用了路由的“URL反向查找”功能,用于反向查找指定action的URL。

      打開/yabe/app/views/tags/display.html標簽并修改: ?

      ${_post.title}

      ?

      刷新主頁,單擊博文標題以顯示博文內(nèi)容。非常好,但是這個頁面缺少一個返回主頁的鏈接。OK,讓我們打開/yabe/app/views/main.html模板,完成標題的鏈接:

      ?

      About this blog

      ${blogTitle}

      ${blogBaseline}

      第五篇:play手把手教你創(chuàng)建一個博客項目-02.迭代編寫數(shù)據(jù)模型代碼

      02.迭代編寫數(shù)據(jù)模型代碼

      下面,我們將開始為我們的博客引擎寫一個數(shù)據(jù)模型。

      JPA介紹

      在play應用程序(事實上也包括所有設計良好的應用程序)里,模型層是最為核心的地方。play是一個域驅(qū)動類型的數(shù)據(jù)表現(xiàn)框架,既然我們想要創(chuàng)建一個博客引擎,那么模型層所需要的類(比如User/Post和Comment)就應當首先考慮。

      因為大多數(shù)模型對象都需要在應用程序重新啟動后能夠繼續(xù)保存數(shù)據(jù),因此,我們就必須把它們保存在一個可持久化的存儲器里。通常,我們會選擇一個關系數(shù)據(jù)庫來保存數(shù)據(jù)。但是,由于java是面向?qū)ο蟮恼Z言,因此,我們將使用對象關系映射來減少匹配阻抗。

      Java Persistence API(JPA)是一個Java規(guī)范,它定義了一個標準的對象關系映射API集。作為JPA規(guī)范的實現(xiàn),play使用眾所周知的Hibernate框架來實現(xiàn)JPA。使用基于Hibernate API的JPA的一個優(yōu)勢就是所有映射都是在java對象里進行聲明的。

      如果在此之前你曾經(jīng)用過Hibernate或JPA,那么在play里使用JPA你會感到非常驚訝,因為在Play里使用Hibernate或JPA實在是太簡單了,它不需要進行任何配置即可正常工作~!

      如果你不知道什么是JPA,哈哈,請在繼續(xù)下面的課程之前先補補課some of these simple presentations。

      創(chuàng)建第一個模型類User 接下來我們將開始為博客引擎編寫代碼,首先是創(chuàng)建User類,接下來讓我們創(chuàng)建/yabe/app/models/User.java類: package models;

      import java.util.*;import javax.persistence.*;

      import play.db.jpa.*;

      @Entity public class User extends Model {

      public String email;public String password;public String fullname;public boolean isAdmin;

      public User(String email, String password, String fullname){ this.email = email;this.password = password;this.fullname = fullname;} } @Entity注釋使User類成為一個可被管理的JPA實體,其繼承的Model超類自動為其提供了一系列非常有用的JPA幫助方法(后面我們會作介紹)。所有User類的fields(以下均稱為字段,不再提示)都會自動持久化到數(shù)據(jù)庫里。默認情況下,數(shù)據(jù)庫表的名稱為 ‘User’。在某些情況下,默認的表名可能會與數(shù)據(jù)庫的保留關鍵字沖突,這時就需要對數(shù)據(jù)庫表名進行定制,比如針對User類,可以注釋為@Table(name=“blog_user”)。

      繼承play.db.jpa.Model類并不是必須的,你可以繼續(xù)使用原始的JPA。但繼承Model類是一個好的選擇,通過繼承Model類,你可以通過它提供的幫助方法很方便的對實體類進行操作。

      如果之前你用過JPA,那么你應該知道每個JPA實體都必須提供一個@Id屬性。在這里,Model超類提供了一個自動生成數(shù)字型ID的功能,在很多情況下已經(jīng)足夠了。

      注意,請不要把Model自動提供的ID當作功能性標識符使用,只能把它當成是技術(shù)性標識符使用。通常情況下,自動生成的數(shù)字ID作為一個技術(shù)標識符是個較好的主意。

      如果你是一個經(jīng)驗豐富的java開發(fā)者,那么你就會知道在模型對象里的字段應該是private的,訪問這些字段的方式是為這些字段創(chuàng)建getter/setter方法。但是,在play里,字段是用public修飾的,其目的是為了編寫代碼的量,請別擔心,事實上play會小心照顧好這些字段,自動為其生成getter/setter。刷新一下應用程序主頁,看看有些什么變化沒。事實上,除非代碼有錯誤,你應該看不到任何變化。play已經(jīng)自動編譯和加載了User類,但是這并沒有為應用程序添加任何新的特征。

      編寫第一個測試程序 在play里,測試新創(chuàng)建的User類的好方法就是編寫一個JUnit單元測試。這個測試將允許你對User進行測試。

      要想進行測試,你得把play切換到test模式下。首先停止當前正在運行的應用程序,在命令行輸入如下命令,以切換到測試模式: ~$ play test 除了加載了一個test runner模塊,以允許你在瀏覽器直接運行測試組件外,play test命令和play run很相似。

      當play運行與測試模式時,Play將自動切換到測試框架ID,并加載相應的application.conf配置文件,參考framework ID documentation了解更多信息。在瀏覽器打開http://localhost:9000/@tests URL地址,就可以看到test runner了。試著選擇所有默認的測試并運行它們,所有的結(jié)果都應該是綠色的?其實這些測試并沒有進行任何實質(zhì)性的測試。為了測試User模型(適用于所有的模型類),我們打算使用JUnit測試。正如你所看到的一樣,play已經(jīng)提供了一個默認的BasicTests.java文件,讓我們打開看看(/yabe/test/BasicTest.java): import org.junit.*;import play.test.*;import models.*;

      public class BasicTest extends UnitTest { @Test public void aVeryImportantThingToTest(){ assertEquals(2, 1 + 1);} } 刪除默認的無用的測試(aVeryImportantThingToTest),并創(chuàng)建一個新的測試,在其中將試著創(chuàng)建一個新的user,并得到它:

      @Test public void createAndRetrieveUser(){ // Create a new user and save it new User(“bob@gmail.com”, “secret”, “Bob”).save();

      // Retrieve the user with e-mail address bob@gmail.com User bob = User.find(“byEmail”, “bob@gmail.com”).first();

      // Test assertNotNull(bob);assertEquals(“Bob”, bob.fullname);} 正如你所看到的一樣Model超類提供了兩個非常有用的方法save()and find()。在play管理手冊的JPA support節(jié),你可了解更多Model類的方法。在test runner里選擇BasicTests.java,單擊start進行測試,可以看到結(jié)果全是綠色。

      接下來,我們需要在User里創(chuàng)建一個驗證user的username和password是否正確的方法(通過username和password來找到user)。打開User.java源文件,添加connect()方法:

      public static User connect(String email, String password){ return find(“byEmailAndPassword”, email, password).first();} 在BasicTests.java里添加測試代碼:

      @Test public void tryConnectAsUser(){ // Create a new user and save it new User(“bob@gmail.com”, “secret”, “Bob”).save();

      // Test assertNotNull(User.connect(“bob@gmail.com”, “secret”));assertNull(User.connect(“bob@gmail.com”, “badpassword”));assertNull(User.connect(“tom@gmail.com”, “secret”));} 每次修改后,你都可以直接在test runner里運行所有的測試。

      創(chuàng)建Post類

      Post類用展現(xiàn)發(fā)表的博客:

      package models;

      import java.util.*;import javax.persistence.*;

      import play.db.jpa.*;

      @Entity public class Post extends Model {

      public String title;public Date postedAt;

      @Lob public String content;

      @ManyToOne public User author;

      public Post(User author, String title, String content){ this.author = author;this.title = title;this.content = content;this.postedAt = new Date();} } 在這里,我們使用@Lob注釋來告訴JPA這個字段是一個超大文本數(shù)據(jù)庫類型,用是存儲發(fā)表的內(nèi)容。我們同時用@ManyToOne來聲明Post與User是多對一的關系。意思是每篇博客都是單個用戶寫的,每個用戶可是發(fā)表多篇博客?,F(xiàn)在的PostgreSQL版本還不能存儲用@Lob注釋的String類型字段,解決方法是使用@Type(type = “org.hibernate.type.TextType”)進行注釋。接下來,我們將編寫新的測試代碼用于測試Post類。但是在寫更多測試代碼之前,我們需要在JUnit測試類里做一些工作,比如在當前的測試代碼里,數(shù)據(jù)庫內(nèi)容并不會刪除,因此,我們每運行一次,play就會增加一個新創(chuàng)建的對象,這些對象會越來越多,當進行更高級的測試時,這或許會成為問題。

      因此,讓我們在運行每個測試之前寫一個JUnit setup()方法來刪除數(shù)據(jù)庫: public class BasicTest extends UnitTest {

      @Before public void setup(){ Fixtures.deleteDatabase();}

      ? } @Before是JUnit測試工具最核心的概念。

      正如你所看到的,F(xiàn)ixtures類幫助我們在測試期間管理數(shù)據(jù)庫。接下來,我們將編寫下一個測試:

      @Test public void createPost(){ //創(chuàng)建一個新的user,并保存

      User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();

      // 創(chuàng)建一個新post new Post(bob, “My first post”, “Hello world”).save();

      // 測試上一步是否創(chuàng)建了新的post assertEquals(1, Post.count());

      // 獲取所有“Bob”發(fā)表的posts List

      bobPosts = Post.find(“byAuthor”, bob).fetch();

      // Tests assertEquals(1, bobPosts.size());Post firstPost = bobPosts.get(0);assertNotNull(firstPost);assertEquals(bob, firstPost.author);assertEquals(“My first post”, firstPost.title);assertEquals(“Hello world”, firstPost.content);assertNotNull(firstPost.postedAt);} 千萬不要忘記了導入java.util.List,否則會出現(xiàn)編譯錯誤。

      編寫Comment類

      最后一件事就是創(chuàng)建Comment類,為發(fā)表的博客提供評論的能力。package models;

      import java.util.*;import javax.persistence.*;

      import play.db.jpa.*;

      @Entity public class Comment extends Model {

      public String author;public Date postedAt;@Lob public String content;

      @ManyToOne public Post post;

      public Comment(Post post, String author, String content){ this.post = post;this.author = author;this.content = content;this.postedAt = new Date();} } Comment的測試代碼: @Test public void postComments(){ // Create a new user and save it User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();

      // Create a new post Post bobPost = new Post(bob, “My first post”, “Hello world”).save();

      // Post a first comment new Comment(bobPost, “Jeff”, “Nice post”).save();new Comment(bobPost, “Tom”, “I knew that!”).save();

      // Retrieve all comments List bobPostComments = Comment.find(“byPost”, bobPost).fetch();

      // Tests assertEquals(2, bobPostComments.size());

      Comment firstComment = bobPostComments.get(0);assertNotNull(firstComment);assertEquals(“Jeff”, firstComment.author);assertEquals(“Nice post”, firstComment.content);assertNotNull(firstComment.postedAt);

      Comment secondComment = bobPostComments.get(1);assertNotNull(secondComment);assertEquals(“Tom”, secondComment.author);assertEquals(“I knew that!”, secondComment.content);assertNotNull(secondComment.postedAt);} 這里,你可以看到在Post和Comment之間進行導航并不容易:我們需要使用查詢來找到一個博文的所有評論。在這里我們還有更好的方法,方法就是在Post類里定義它與Comment之間的一多對關系。在Post類里添加一個comments域:

      ...@OneToMany(mappedBy=“post”, cascade=CascadeType.ALL)public List comments;

      public Post(User author, String title, String content){ this.comments = new ArrayList();this.author = author;this.title = title;this.content = content;this.postedAt = new Date();}...請注意,在這里我們使用mappedBy屬性來告訴JPA,Comment類的post字段是comment的擁有者,由post負責維護它們的關系。當你用JPA定義一個一個雙向關系時,明確指定哪邊負責維護關系非常重要。在這種情況下,既然Comment的多個實例隸屬于一個Post,因此,我們就在Comment.post上定義反轉(zhuǎn)關系。同時,我們設置cascade屬性來告訴JPA,當我們刪除一個Post實例里,要JPA自動同步刪除其關聯(lián)的comments。

      定義好上述關系后,我們需要在Post類里添加一個幫助方法用于添加評論: public Post addComment(String author, String content){ Comment newComment = new Comment(this, author, content).save();this.comments.add(newComment);this.save();return this;} 其測試代碼為:

      @Test public void useTheCommentsRelation(){ // Create a new user and save it User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();

      // Create a new post Post bobPost = new Post(bob, “My first post”, “Hello world”).save();

      // Post a first comment bobPost.addComment(“Jeff”, “Nice post”);bobPost.addComment(“Tom”, “I knew that!”);

      // Count things assertEquals(1, User.count());assertEquals(1, Post.count());assertEquals(2, Comment.count());

      // Retrieve Bob's post bobPost = Post.find(“byAuthor”, bob).first();assertNotNull(bobPost);

      // Navigate to comments assertEquals(2, bobPost.comments.size());assertEquals(“Jeff”, bobPost.comments.get(0).author);

      // Delete the post bobPost.delete();

      // Check that all comments have been deleted assertEquals(1, User.count());assertEquals(0, Post.count());assertEquals(0, Comment.count());} 測試下看看:

      使用Fixtures來編寫更復雜的測試 在開發(fā)編寫更復雜的測試之前,我們通常需要提前準備一系列的測試數(shù)據(jù),F(xiàn)ixtures類允許我們在一個YAML文件里描述需要準備數(shù)據(jù)的模型,它允許我們在進行任何測試之前加載這個yaml文件。

      編輯/yabe/test/data.yml文件,對User模型的數(shù)據(jù)進行描述:

      User(bob): email: bob@gmail.com password: secret fullname: Bob...OK,這個data.yml文件有點大,我們已經(jīng)提前準備好了,還是下載吧download it here。

      接下來,我們將在測試代碼里加載這個文件里描述的數(shù)據(jù),并對它進行測試: @Test public void fullTest(){ Fixtures.loadModels(“data.yml”);

      // Count things assertEquals(2, User.count());assertEquals(3, Post.count());assertEquals(3, Comment.count());

      // Try to connect as users assertNotNull(User.connect(“bob@gmail.com”, “secret”));assertNotNull(User.connect(“jeff@gmail.com”, “secret”));assertNull(User.connect(“jeff@gmail.com”, “badpassword”));assertNull(User.connect(“tom@gmail.com”, “secret”));

      // Find all of Bob's posts List

      bobPosts = Post.find(“author.email”, “bob@gmail.com”).fetch();assertEquals(2, bobPosts.size());

      // Find all comments related to Bob's posts List bobComments = Comment.find(“post.author.email”, “bob@gmail.com”).fetch();assertEquals(3, bobComments.size());// Find the most recent post Post frontPost = Post.find(“order by postedAt desc”).first();assertNotNull(frontPost);assertEquals(“About the model layer”, frontPost.title);

      // Check that this post has two comments assertEquals(2, frontPost.comments.size());

      // Post a new comment frontPost.addComment(“Jim”, “Hello guys”);assertEquals(3, frontPost.comments.size());assertEquals(4, Comment.count());} 更多關于YAML的內(nèi)容,請閱讀YAML manual page。

      下載play手把手教你創(chuàng)建一個博客項目-08.添加身份認證word格式文檔
      下載play手把手教你創(chuàng)建一個博客項目-08.添加身份認證.doc
      將本文檔下載到自己電腦,方便修改和收藏,請勿使用迅雷等下載。
      點此處下載文檔

      文檔為doc格式


      聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔相關法律責任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進行舉報,并提供相關證據(jù),工作人員會在5個工作日內(nèi)聯(lián)系你,一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

      相關范文推薦