文档库 最新最全的文档下载
当前位置:文档库 › playframework1.25入门学习手册

playframework1.25入门学习手册

配置play环境

把play的路径添加到系统环境变量的PATH路径中

play

1.进入CMD环境,测试配置是否成功

2.这里我们用samples-and-tests 下的yabe项目来做例子。

3.在cmd中 play new yabe

4.进入创建的目录运行play run命令. 在浏览器中输入http://localhost:9000查看

创建的项目是否成功。

5.使用 play eclipsify 表示把项目转换成一个ECLIPSE项目。

6.输入play test 表示以测试模式启动。在浏览器中输入

http://localhost:9000/@tests 表示进入测试JUNIT页面,并可进行测试

7.创建实体BEAN,play的实体BEAN使用的是JPA的实体

8.把项目导入eclipse中,在models包中创建类,内容如下:

package models;

import javax.persistence.Entity;

import play.db.jpa.Model;

@Entity

public class User extends Model {

public String email;

public String password;

public String fullname;

public String isAdmin;

public User(String email, String password, String fullname) {

this.email = email;

this.password = password;

this.fullname = fullname;

}

}

关于实体中类的注解可以通过查看JPA2.0的相关文档来进行了解.

注意一点,我在创建的实体类中并没有添加ID属性,但是其实ID属性是必须的属性,如果我们在实体类中没有显示的指定ID属性,PLAY会给我们创建一个默认的id属性,这个属性的值为自动增加值。

集成JUNIT单元测试

在 test包目录下新建一个UserTest的测试类,继承UnitTest类,如下:

import https://www.wendangku.net/doc/2512055294.html,er;

import org.junit.Test;

import play.test.UnitTest;

public class UserTest extends UnitTest {

@Test

public void createAndRetrieveUser() {

//添加

User user = new User("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,","123456","小机");

assertNotNull(user.save());

//查询条件下的所有信息,并返回第一个

User search = user.find("byEmailLike", "%gmail%").first();

assertNotNull(search);

assertEquals("123456", search.password);

}

}

运行 play test 在浏览器中输入 http://localhost:9000/@tests 选择UserTest点击 start 按钮测试。

在User实体中编写一个查询的方法,并在测试类中添加一个测试方法,不需要重启浏览器,直接进行测试。查看效果。

public static User connect(String email, String password) {

return User.find("byEmailLikeAndPassword", "%" + email + "%", password) .first();

}

@Test

public void testConnectMethod() {

//添加

User user = new User("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,","123456","小机");

assertNotNull(user.save());

//查询

assertNotNull(User.connect("gmail", "123456"));

assertNull(User.connect("test", "123456"));

assertNull(User.connect("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,", "aa"));

assertNotNull(User.connect("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,", "123456"));

}

新建一个Post实体类,类的关系与User为多对一的关系。

package models;

import java.util.Date;

import javax.persistence.Entity;

import javax.persistence.Lob;

import javax.persistence.ManyToOne;

import play.db.jpa.Model;

@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();

}

}

创建一个测试方法:

@Test

public void createPost() {

//添加

User user = new User("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,","123456","小机");

assertNotNull(user.save());

Post post = new Post(user, "title","content");

assertNotNull(post.save());

assertEquals(1, Post.count());

List list = Post.find("byAuthor", user).fetch();

assertEquals(1, list.size());

Post firstPost = list.get(0);

assertNotNull(firstPost);

assertEquals("title",firstPost.title);

assertEquals("content",firstPost.content);

assertNotNull(firstPost.postedAt);

assertEquals(user,firstPost.author);

}

查看测试结果。

新建一个Comment实体类,实体类与Post为多对一的关系。

package models;

import java.util.Date;

import javax.persistence.Entity;

import javax.persistence.Lob;

import javax.persistence.ManyToOne;

import play.db.jpa.Model;

@Entity

public class Comment extends Model {

public String author;

@Lob

public String content;

public Date postedAt;

@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 createComments() {

User user = new User("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,","123456","小机");

assertNotNull(user.save());

Post post = new Post(user, "title","content");

assertNotNull(post.save());

new Comment(post,"author1","content1").save();

new Comment(post,"author2","content2").save();

List list = Comment.find("byPost", post).fetch();

assertEquals(2,list.size());

Comment firstComment = list.get(0);

assertEquals("author1",firstComment.author);

assertNotNull(firstComment.postedAt);

}

为Post添加一对多关系

mappedBy表示找到Comment类中的post对象进行反转

@OneToMany(mappedBy="post",cascade=CascadeType.ALL)

Set comments;

public Post(User author, String title, String content) { comments = new LinkedHashSet(0);

this.author = author;

this.title = title;

this.content = content;

this.postedAt = new Date();

}

添加测试方法:

@Test

public void postAddComments() {

User user = new User("yh.sniaw@https://www.wendangku.net/doc/2512055294.html,","123456","小机");

assertNotNull(user.save());

Post post = new Post(user, "title","content");

assertNotNull(post.save());

https://www.wendangku.net/doc/2512055294.html,ments.add(new Comment(post,"author1","content1"));

https://www.wendangku.net/doc/2512055294.html,ments.add(new Comment(post,"author2","content2"));

post.save();

Post firstPost = Post.find("byTitle", "title").first();

assertEquals(2,https://www.wendangku.net/doc/2512055294.html,ments.size());

assertEquals(2,Comment.count());

}

编写视图显示

1.添加在服务器启动时需要处理的事情。如加载一些基础数据:

在models中添加一个Bootstarp类。此类继承Jo b类。

package models;

import play.jobs.Job;

import play.jobs.OnApplicationStart;

import play.test.Fixtures;

@OnApplicationStart

public class Bootstarp extends Job {

public void loadUsers() {

if (User.count() < 1) {

Fixtures.loadModels("init_user.yml");

}

}

}

在conf目录添加init_user.yml文件。文件内容可以从test包下的data.yml文件中复制出来。并做一些修改。

代码格式每一个对象用空行表示结束。值中–表示引用一个对象, ->表示换行

User(bob):

email: bob@https://www.wendangku.net/doc/2512055294.html,

password: secret

fullname: Bob

isAdmin: true

User(jeff):

email: jeff@https://www.wendangku.net/doc/2512055294.html,

password: secret

fullname: Jeff

以上代码为 YAML代码,代码语法见YAML语法说明:

以上代码表示添加一个User对象,对象名称为bob,构造方法中传入了三个参数与值。

创建一个测试方法进行测试,看看USER对象是否已经创建。代码如下:

@Test

public void showUser() {

System.out.println(User.count());

User user = User.find("byEmail", "bob@https://www.wendangku.net/doc/2512055294.html,").first();

assertNotNull(user);

System.out.println(user);

}

通过 play test方式启动服务器,并进行测试。

以上的测试好像没有用。加载完成后我是能查询到。通过运行环境不知道能不能行。

现在我们停止测试环境的运行,启动运行环境。 Play run

现在我们修改下应用的默认首页。

打开 controllers下的Application文件,修改index方法:

public static void index() {

Post firstPost = Post.find(" order by postedAt desc").first();

List postList = Post.find(" order by postedAt desc").from(0).fetch(10);

render(firstPost,postList);

}

打开Application中index对应的视图文件,views/Application/index.html把代码修改成如下内容:

#{extends 'main.html' /}

#{set title:'Home' /}

#{if firstPost}

${firstPost.title}

#{if postList}

当前页数据

#{list items:postList, as:'oldPost'}

${oldPost.title}

class="post-date">${oldPost.postedAt.format('yyyy-MM-dd')}

 | ${https://www.wendangku.net/doc/2512055294.html,ments.size()}

comment${https://www.wendangku.net/doc/2512055294.html,ments.size().pluralize()}

#{if https://www.wendangku.net/doc/2512055294.html,ments}

, last by ${https://www.wendangku.net/doc/2512055294.html,ments.toArray()[-1].author}

#{/if}

#{/list}

#{/if}

#{/if}

#{else}

There is currently nothing to read here.

#{/else}

注意上面代码中的红色部分内容,pluralize表示结果是否大于1,如果大于返回一个s, format可以对日期进行格式化,

XXXList.toArray()[-1]表示查询List中最后一个值。

nl2br()表示把\n转换成
nl 很容易看成是n1 正确的是NL

当然上面这样都是groovy的语法

上面提示这些东西是因为官方的tutoral中写的方式不对,找了下groovy的语法后添加正确。

创建自定义标签

自定义标签可以理解为页面模板(可在自定义标签中写HTML信息,并可以定义属性,在引用标签时把属性传入进来)

标签定义:在 views/tags/目录下创建html页面就是标签。如: display.html

标签引用:在页面中使用 #{display 参数:参数值 /} 其中display为标签的HTML名称标签中使用参数:在标签中使用参数以“_”开始,后面是参数名称。

标签使用例子:

定义标签:

*{这是一个注释display post Post and as in ('full','teaser','first')}*

${_post.title}

#{if _as != 'teaser'}

Detail:

${_post.content.nl2br()}

#{/if}

#{if _as == 'full'}

${_https://www.wendangku.net/doc/2512055294.html,ments.size()?:'no'}

Comment${_https://www.wendangku.net/doc/2512055294.html,ments.size().pluralize()}

#{if _https://www.wendangku.net/doc/2512055294.html,ments}

#{list items:_https://www.wendangku.net/doc/2512055294.html,ments, as:'comment'}

Detail:

${comment.content.escape().nl2br()}

#{/list}

#{/if}

#{/if}

index.html页面引用标签:

#{extends 'main.html' /}

#{set title:'Home' /}

#{if firstPost}

*{引用自定义标签}*

#{display post:firstPost, as:'first' /}

#{if postList}

当前页数据

#{list items:postList, as:'oldPost'}

*{引用自定义标签}*

#{display post:oldPost,as:'teaser' /}

#{/list}

#{/if}

#{/if}

#{else}

There is currently nothing to read here.

#{/else}

测试查看效果:

修改布局

A.现在我们打开views/main.html页面,修改页面的外观。

#{get 'title' /}

href="@{'/public/stylesheets/main.css'}">

#{get 'moreStyles' /}

href="@{'/public/images/favicon.png'}">

#{get 'moreScripts' /}

#{doLayout /}

Yabe is a (not that) powerful blog engine built with the itfuture

as a tutorial application.

表示式语言符号

注意:上面的代码中我们使用了:

可参见https://www.wendangku.net/doc/2512055294.html,/documentation/1.2.4/templates#syntax

# {}: 表示引用模板(标签)

${}: 表示表达式

@{}: 表示引用静态资源

%{}% : 使用一段脚本。

&{}: 表示引用一段消息

注意,上面红色部分引用了两个变量值,这时候我们需要在ACTION中控制这两个参数值。但是由于这是一个布局模块文件,不需要在每一个控制器中重新赋值的情况下,我们可以在Application.java文件中定义一个方法,这个方法用@Before来注解,表示方法在每一个动作执行前调用。

@Before

static void addDefaults() {

renderArgs.put("blogtitle", Play.configuration.getProperty("blog.title"));

renderArgs.put("blogbaseline",

Play.configuration.getProperty("blog.baseline"));

}

上面的代码中我们在renderArgs中存放了两个值:bolgtitle,blogbaseline,那么这两个值在页面中就可以直接去使用。

同时,我在方法使用了Play.configuration.getProperty方法得到配置的两个参数值。Play.configuration表示得到conf/application.conf中配置的参数值。

现在我们打开application.conf文件,配置上面使用到的两个参数值。

blog.title=博客标题

blog.baseline=博客基线

运行 play run,测试下效果:

从上图我们可以看到。信息是出来了,但是还有乱码的存在,现在我们处理下乱码问题:其实这问题相对简单,把application.conf文件修改为UTF-8编码格式,同时打开

application.conf文件时使用eclipse工具打开就不会出现问题。

给模块添加一些样式,让页面看出来更加好看些。

把 main.css文档中的内容复制到你的项目下面 public/stylesheets目录下的main.css

文件中。

通过上面的的邮件列表页面我们学习了一定的知识,现在我们继续添加邮件的查看与更新功能。

A.在Application.java中创建一个show的方法,方法中传入一个Post的ID属性,public static void show(Long id) {

Post post = Post.findById(id);

render(post);

}

B.在views/Application/创建一个与方法同名的HTML文件 show.html。

#{extends 'main.html' /} *{引用一个模板}*

#{set title:'show post' /} *{设置模板中的参数值}*

#{display post:post, as:'full'/} *{调用一个自定义标签}*

C.修改views/tags/display.html的自定义标签,把

${_post.title} 替换为:

${_post.title}

D.修改views/main.html模板页面中

${blogtitle}

替换为:

${blogtitle}

运行 play run 查看效果。

自定义URL路由规则:

默认(所有)的URL路由规则都需要在conf/routes 文件中配置,

# Catch all

* /{controller}/{action} {controller}.{action} 上面代码的意思:

* 表示 GET/POST都可以,

/{controller}/{action}表示客户端访问路径。

{controller}.{action} 表示控制器类与方法

具体说明:

https://www.wendangku.net/doc/2512055294.html,/documentation/1.2.4/routes#syntax

那么通过上面的说明我们就可以定义show.html的客户端访问路径。

GET /posts/{id} Application.show

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

需要把自定义放到默认的前面,否则找不到。

@Before

static void addDefaults() {

renderArgs.put("blogtitle", Play.configuration.getProperty("blog.title"));

renderArgs.put("blogbaseline",

Play.configuration.getProperty("blog.baseline"));

Map map = params.data; //此处可以得到请求的参数值,并可对值进行处理

}

注意上面的红色部分代码。现在标记出来,在实际的项目中我们可能会用到。

添加一个分页处理的方式:

A . 打开实体BEAN Post 类,添加如下两个方法:

public Post previous() {

Post previous = Post.find(" postedAt < ? order by postedAt desc", postedAt).first();

return previous;

}

public Post next() {

Post next = Post.find(" postedAt > ? order by postedAt desc", postedAt).first();

return next;

}

B.修改show.html页面。在页面后边添加如下信息:

    #{if post.previous()}

    #{/if}

    #{if post.next()}

    #{/if}

运行查看效果:

给邮件添加回复功能:

A.在Post实体中添加一个方法:

public void addComment(String author, String content) {

Comment comment = new Comment(this,author,content);

https://www.wendangku.net/doc/2512055294.html,ments.add(comment);

this.save();

}

相关文档
相关文档 最新文档