首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

play札记

2012-08-17 
play笔记?注:此为个人学习笔记,内容可能有些杂乱,仅供参考。以下内容使用play-1.2.4版本1、常用命令1)、play?

play笔记

?

注:此为个人学习笔记,内容可能有些杂乱,仅供参考。

以下内容使用play-1.2.4版本

1、常用命令

1)、play??new??<项目名>

2)、play??run???<项目名>

3)、play??eclipsify??<项目名>

4)、play??war??<项目名>??-o?<war包名,需加.war,,如??webplay.war??--zip

生成webplay.war.war

2、在eclipse中调试

Play转换eclipse项目时,在eclipse目录中生成了三个启动配置:

1)、JPDA:连接到已经启动的Play?Server,实现alive调试

2)、webplay:本地运行

3)、Test:测试

选中它们,右键执行Run?As,即可完成相应的任务。

直接Debug?As?执行webplay会报错:

Error?occurred?during?initialization?of?VM

agent?library?failed?to?init:?jdwp

ERROR:?Cannot?load?this?JVM?TI?agent?twice,?check?your?java?command?line?for?duplicate?jdwp?options.

需要:

打开webplay.launch,找到

<stringAttribute?key="org.eclipse.jdt.launching.VM_ARGUMENTS"?value="-Xdebug?-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n?-Dplay.debug=yes?-Dplay.id=?-Dapplication.path??…/>

将-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n?去掉。

然后Debug?As,即可成功启动调试。附加Play源码后,即可调试Play本身。

3、play模式

Play分为开发模式和生产模式两种,而切换的配置在application.conf中:

??Application.mode=dev?生产模式请改为:prod

??主要区别在于开发模式中您无需重启server,每次请求都会查看是否有文件发生改变,改变即编译,这对于传统Java?EE开发人员无疑是相当敏捷的。而这种方式同样会导致性能下降,所以生产模式中就不会这样了,而是采用预编译机制。

开发模式要有第一次http请求,才启动application

4、controller

controller中的几个作用域:

????1)、session这儿的session只支持您放里面放String类型,而不是和传统JEE中任何对象都可以放到session中。这儿的session和rails的类似。

????2)、flash?跨请求的存储对象?

????3)、params??基本相当于request.getParameters();

????4)、renderArgs??渲染到模板的数据,上面代码中您看到的render里面的就是放到了这个renderArgs里面了。还有个validation存放验证数据。?

??基类Controller里定义了很多好用的方法:如果想使用ajax返回JSON,则使用renderJSON()??play使用的json序列化工具是gson.jar,。想返回一个文件流,使用renderBinary(File?f,String?name)方法

5、工具包

play.libs.*

6、play?session

Play框架认为一边是数据库保存状态,一边是浏览器也可以保存状态,那么还要中间件MVC保存Session状态干什么呢?

HttpSession有很多问题,虽然可以处理针对某个用户的状态,但是万一用户中途离开怎么办,HttpSession对资源消耗,以及在可伸缩性方面是有问题的。Play框架秉承share?nothing架构思想,不再像黑客那样破解原本自然正常Http模型,然后强行植入状态,无状态架构可以并行同时输出多个页面,提高Web性能。

session.put(String?name,String?value);

String??value?=?session.get(String?name);

Play?session只能保存字符串

“无共享”架构

7、模板

一个基于Groovy的强大的模板引擎,具有多层继承,定制用户标签的能力,Play框架认为JSP?&?Expression?Language模板机制很好,但是需要太多配置,吸收其模板设计,剔除配置。

8、RESTFul

众所周知的Servlet?API?和Struts其实是扭曲的,使用奇怪的API将Http协议隐藏起来,Play框架认为一个Web应用框架应该给用完整的?直接的对Http调用和使用,这其实就是RESTFul精神。

9、“/”

默认Play认为“/”是很重要的,例如下面这个route,

GET?/clients?Client.index

会匹配/clients但是不会匹配/clients/,你可以通过在“/”后加上一个问号,告诉Play你想让那个route匹配到后面的"/",例如

GET/clients/??Clients.index

URI模式不能有任何可选的部分,除了那个"/"?(不理解)

10、package

Route的最后一部分是Java调用定义,这部分是由一个action方法的全名定义的,并且这个action必须是一个控制器类中的静态的公共方法,控制器类必须定义在包controllers中且必须是play.mvc.Controller的子类。你可以在控制器类之前增加一个Java包如果它不是直接定义在controllers包中,包controllers本身是默认包含的,所以你不需要指定它。

例如:

GET?/admin?admin.Dashboard.index

11、Render渲染页面

默认渲染html文件

views目录下对应??包名/类名/方法名.html

在调用?render?方法之前,你可以使用编程的方式设置响应的格式。例如,为了提供一个媒体类型?media?type?为?text/css?的层叠样式表,而是以你可以这样做:

request.format?=?"css";??

但不会解析对应的文件类型,如设置request.format=”jsp”,并不会解析jsp文件,而是以文本的形式显示出所有的源码.。

12、Route

1)?定义一个URL,其中id指定为'home',我可以使用静态参数定义另外一个route

GET???/home???????Application.page(id:'home')

GET???/page/{id}???Application.page

当page?ID为'home'时,第一个route和第二个route是等价的,但是,它的优先级要高一些,当你使用ID?'home'?调用Application.page时,它是默认被调用的。

2)?路由优先级

很多路由可以匹配相同的请求,如果有冲突的话,则使用第一个定义

3)长路由配置

去除routes文件的

#?Catch?all

#*???????/{controller}/{action}??????????????????{controller}.{action}

这路由配置

*/home/{id}???????????????????????????????????jc.JcApplication.bye

匹配

http://127.0.0.1:9000/home/11235

13、controller

业务逻辑代码通常位于模型(model)层。客户端(比如浏览器)无法直接调用其中的代码,所以模型对象提供的功能,必须作为资源以URI方式暴露给外部。

客户端使用HTTP协议来操作这些资源,从而调用了内部的业务逻辑。但是,这种从资源到模型之间的映射是单向的:我们可以根据需要提供不同粒度的资源,可以虚拟出一些资源,还可以给某些资源起别名.

1)使用@As注解,我们可以指定日期格式。例如

archives?from=21/12/1980

public?static?void?articlesSince(@As("dd/MM/yyyy")?Date?from)

14、视图层

Web?开发框架的使用者都习惯于使用某种模板技术来生成?HTML?页面,这些技术包括常见的?JSP、ASP?和?PHP?等。Play?框架也提供了自己的模板技术,可以用来动态的创建?HTML、XML、JSON?以及其它文本类型的内容。Play?框架的模板技术使用的是?Groovy?语言。Groovy?语言的灵活性和简洁性使得?Play?框架的模板简单而且易用。在模板中可以混用静态内容和生成动态内容的各种元素。

${…}对一个表达式进行求值

@{…}和@@{…}分别用来调用控制器中动作方法的相对URL和绝对URL

&{‘…’}显示经过i18n后的内容

*{…}*注释

%{…}%添加复杂的Groovy脚本,可以声明变量和添加语句。

#{…}用来调用Play框架或是开发人员自定义的标签

?

#{extends??‘…’/}和#{doLayout??/}实现模板之间的继承

15、i18n

zh_cn:?简体中文

zh_hk:?繁体中文(中国香港)??

zh_tw:?繁体中文(中国台湾地区)

en-hk:?英语(香港)

en_us:?英语(美国)

en_gb:?英语(英国)

en_ww:?英语(全球)

ja_jp:?日语(日本)

ko_kr:?韩文(韩国)

16、Action链

在play中没有Servlet?API?forward?的等价物。每一个HTTP?request只能调用一个action。如果我们需要调用另一个,必须通过重定向,让浏览器访问另一个URL来访问它。这样的话,浏览器的URL始终与被执行的action保持一致,实现?Back/Forward/Refresh?的管理就容易多了。

17、拦截器(Interceptions)

一个controller可以定义多个拦截器方法。拦截器作用于一个controller及其所有子类的所有action方法上。对于定义一些所有action共用的操作时,使用拦截器非常有用,这些方法必须为?static?,但不一定是?public?。

@Before

@After

@Finally

@Catch???????异常,传递Throwable对象

@With????????注解在类申明上面,可使用指定的controller定义的拦截方法

18、Session和Flash?scopes

在多个HTTP请求之间共用数据,可以把它们保存在Session或Flash域中。保存在Session中的数据,对于整个user?session都可用,而保存在flash域中的数据,则仅仅在下一个请求可用。在play中,Session和Flash数据并没有保存在服务器端,而是通过Cookie被加入到每一个HTTP请求中。所以能保存的数据量非常小(不超过4KB),并且只能保存字符串。

cookies都使用了一个密钥进行了加密,所以客户端无法修改cookie数据(否则该数据将无效)。Play的session不是用来当作数据缓存。如果我们需要缓存与session相关的某些数据,可以使用Play内置的缓存机制Cache,并使用?session.getId()?作为key来保存。

19、持久化

(1)Play当找到一个或一个以上的类有注解@javax.persistence.Entity会自动启动Hibernate?entity?manager。

JPA.em().createQuery(“”);

(2)事务,play会默认自动事务管理,以一个http请求至响应为单位。当请求失败或响应出错,事务自动回滚。

手动设置事务管理,

JPA.setRollbackOnly()??强制事务回滚

在控制类的方法上加注解

@play.db.jpa.Transactional(readOnly=true)??设置事务为只读

@play.db.jpa.NoTransaction????不使用事务,play将不会从连接池获得连接,这将提高运行速度。

(3)entites?继承play.db.jpa.Model?用Long?id作为主键

??entites继承play.db.jpa.GenericModel自已使用@Id设置主键

??@GeneratedValue??@GenericGenerator?设置主键生成策略

(4)refresh()?防止实体暗自更新,,类似hibernate中的evit(Ojbect)

(5)entites继承自JPASupport/JPAModel,没有显式调用save()则不会自动保存(不推荐使用),改为继承GenericModel

Play描述有误?测试结果,无论继承Model或GenericModel没有显示调用save(没有update方法)都不会自动保存或更新

(6)自动生成表结构

继承Model须显式声明@Table

继承GenericModel则只须声明@Entity

19、play.libs

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

20、使用memcached

配置application.conf

#?Enable?memcached?if?needed.?Otherwise?a?local?cache?is?used.

memcached=enabled

#

#?Specify?memcached?host?(default?to?127.0.0.1:11211)

memcached.host=127.0.0.1:11211

热点排行