PlayFramework 1 模板应用 -- Java 对象扩展

涉及到页面显示的问题,用自定义标签总能够能事不少,即使是最原始的自定义 JSP 标签也有人乐此不疲,进化到  Play 中的自定义标签数得上很轻量级的实现,简单的只需要一小页文档 The template engine 就足矣。

概括起来 Play1 支持三种方式自定义标签: HTML 文件方式, 自定义 FastTags, Java 对象扩展方法. 前二者为面向过程的方式,第三种方式为面向对象的方式,是在往某种数据类型追加一个方法。

确切的说针对 Java 对象的方法的扩展并不能称之为自定义标签。

一个这样的场景,股票价格变化值要显示在页面上,根据正,负,零,再加上不同的区域四种条件分别显示为不同的颜色,比如美国分别为绿色,红色和黑色(注: 美国股市显示的颜色正好与中国相反)。假设 priceChange 是 Integer 类型,我们就可以定义对 Integer 对象的扩展,所在类必须继承自 JavaExtensions 类: 阅读全文 >>

PlayFramework 1 输出所有 WS.url() 访问的 URL

记录下这个其实没有多大的意义,新入手 Play 框架的应该直接就是用版本 2 了,只因我们还要系统工作在 Play1 下,所以记下来,估计在 Play2 中已无借鉴作用了。

我们在 Play1 中访问外部 WebService 资源都是用 WS.url(url),然后调用它的 get(), post(), delete() 等相对应的 HTTP 请求方法。我们可以系统中所有通过 WS.url() 访问的 URL, 需找到切面,Play 是在哪里为访问的 URL 创建请求的。

看 WS 类的实现,它是一个 PlayPlugin 插件,其中定义了

private static WSImpl wsImpl = null;

来看 Play 是如何获得 WSImple 实现的,WS 插件的初始化方法中: 阅读全文 >>

Play Framework 2.1(Scala) 调用 WebService 返回 Response

在 Play Framework 2.1 中用 Scala 编程进行 WebService 调用想返回 Response,或 xml, json 结果时,初入可能会费些功夫,因为无论是 WS.url.get,或 post, put 方法返回的都是个 Future[Response] 对象,也就是如何从 Future[Response] 如何分离出 Response 对象的问题。

这里我们 map, 或 match/case 也可以取出其中 response 对象来,如果要作为结果返回还要用到 Await.result() 方法。

为了不把代码出现在摘在页面中,这里插点内容,像是拖延时间的战术。

如果你在使用 Play Framework 2 with Scala 时碰到这个错误:

Error: Cannot find an implicit ExecutionContext, either require one yourself or import ExecutionContext.Implicits.global

依照 899 号 Issue, 解决办法是你必须加上这个引入语句:

import play.api.libs.concurrent.execution.Implicits._

因为里面有我们需要用到的隐式的 global 吧。

下面是我用来请求 WebService 返回 Response 的代码: 阅读全文 >>

Play 2.0 中文资料--翻译附注解(持续更新中)

最近在研究 PlayFramework 2.0,主要关注在使用 Scala 来写 Play 2.0 的应用,下面是从官方文档进行的翻译,并加入了大量的自己的理解与备注( Unmi 注: 起头的蓝色文字)

  1. Play 2.0 中文资料 - 开篇
  2. Play 2.0 中文资料 - 安装 
  3. Play 2.0 中文资料 - 创建一个新的应用 
  4. Play 2.0 中文资料 - 剖析 Play 2.0 应用 
  5. Play 2.0 中文资料 - 使用 Play 2.0 控制台 
  6. Play 2.0 中文资料 - HTTP 编程 
  7. Play 2.0 中文资料 - 搭建你偏爱的 IDE 
  8. Play 2.0 中文资料 - Action, Controller 和 Result 
  9. Play 2.0 中文资料 - HTTP 路由 
  10. Play 2.0 中文资料 - 操控 Result  阅读全文 >>

Scala 2.10.0 新特性之字符串插值

Scala 在处理字符串方面终于也与时俱进了,引入了字符串插件,这在许多脚本语言中就早已这么做了。有了这个特性,字面量字符串和变量连接可以不需要总是用加号进行丑陋的连接了。有些脚本语言会是只对双引号字符串解析其中的变量,单引号的不会,当然Scala 是要区分字符串和字符类型。

直白的讲字符串插值就是,val name="Unmi"; val greeting=s"Hello $name"; greeting 的值就是 "Hello name"。产生效应的就是那个 s 方法。

Scala 2.10.0 为我们提供了三种字符串插值的方式,分别是 s, f 和  raw。它们都是定义在 StringContext 中的方法。

s 字符串插值器

可以解析字符串中的变量,可以调用方法,还能进行计算。实际调用的是  StringContext 中的  s 方法。 阅读全文 >>

Scala 2.10.0 新特性之动态属性、方法

最早的介绍 Scala 语言的书都是以 Scala 的静态类型系统为傲。Scala 也算是个脚本语言,却不像其他许多脚本语言那样类型是动态的,只有执行时才确定,而 Scala 在执行前就确定了类型,比如依赖于比 Java 更强大的类型推断行为。

静态类型不光是变量类型是确定的,还有比如在使用  qual.sel 时,sel 这个属性或是方法(Scala 的访问一致性,属性和方法有时候并没有那么大的区别)必须在 qual 的类型中声明了的。

Scala 思考再三还是加入了 Dynamic Types,这个特性在 Scala 2.9 中是试验性的,必须用 -Xexperimental 进行开启,到了 Scala 2.10.0 中,只有代码中 import scala.language.dynamics 就可用了,或是编译时加 -language:dynamics 选项。

虽然 Scala 2.10.0 加进了 Dynamic Types 特性,但 Scala 仍然是静态类型的语言,因为在编译器同样会检查多出来的类型。

有了 Dynamic Types 之后,Scala 又可更 DSL 了,方法名的动态上可以让它随时包括深刻的业务含义。相比 Java 的 DSL 的能力就太逊了,我们几乎无法在 Java 面前提 DSL 这回事。 阅读全文 >>

使用 Jackson 把 Java 对象转换成 JSON 字串

原来 Java 项目中用的 JSON 组件库主要是 Gson 和 json-lib,Gson 算是很错的库,json-lib 略显寒碜。好啦,最近 Play 2.x 中弃用了 Gson 而采纳了 Jackson,所以现在就来打探一下 Jackson,踩个点吧。

Jackson 号称非常高的性能,听说比另两位兄弟 Gson 和 json-lib 高出一大截,我没有亲测,可是有心人做了,看这个链接 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试) 中的数据。2010 年 8 月份的测试结果,不知现在随着版本的变更是否仍然保持着这种悬殊。

通常我会在把文章开头塞丰满,做足前戏,并不是因为在天涯混习惯了的缘故,况且我在天涯总是讷于言的; 在这里,自己的地盘自己作主,不会有要求码足多少字才能发表的自虐性需求,仅仅是让本文在主页上显示时的的概要不空洞而已,可以简单粗暴的称之为废话。

了了,先了解 Jacson 最贴近实际应用场景的应用,即 Jackson 怎么把一个 Java 生成对应的 JSON 字符串,看看前面的文字有这么多了,直接上一段代码吧,而后再慢慢假设与分解: 阅读全文 >>

Play 2.0 中文资料 - 应用程序全局对象

应用全局设置

全局对象

在你的项目中定义一个 Global 对象,它为你处理应用的全局设置. 这个对象必须定义在默认包中(即不带 package 声明的包).

小贴士: 你也可使用 application.global key 值在在配置中指定自己的 GlobalSettings 实现类名称.

Unmi 注: GlobalSettings.scala 放在 app 目录比较合适,Scala 的 package 层次与目录并不存在严格的对应关系。

要说呢,不带 package 声明的写法确实不是什么好习惯,因为其他带 package 声明的类无法使用它。见:为何Java的有包名的类不能引用默认包中的类。这就对了,本来这个全局对象就不是给别的类用的 - Don't call me, I'll call you。

勾住应用启动和停止事件

你可以覆盖方法 onStartonStop,它们会在应用的生命周期启动,停止时得到通知: 阅读全文 >>

Play 2.0 中文资料 - Play WS API

有时候我们要在 Play 应用中调用其他的 HTTP 服务. Play 是通过它的 play.api.libs.ws.WS 库对此支持的, 该库提供了进行异步的 HTTP 调用.

任何由 play.api.libs.ws.WS 发出的调用都必须返回 Promise[play.api.libs.ws.Response], 我们可以接着可用 Play 的异步机制来处理它.

Unmi 注: 这里有必须挪出 Play 1 和 Play 2 的 WS 稍加对比:

Play 1 中  play.libs.WS 类,Play 2 里是 play.api.libs.ws.WS,Play 2 中许多给外部调用的 API 都放在 play.api.libs 包中了。

Play 1 的 play.libs.WS.WSRequest  中有 get():HttpResponse, getAsync():Promise<HttpResponse>, put():HttpResponse, putAsync():Promise<HttpResponse>,它把同步和异步调用分得很清楚。

而 Play 2 的 play.api.libs.ws.WS.WSRequestHolder 里只有 get(): Promise<Response>, post(): Promise<Response> 这样方法,在这个位置上,它不再分同步还是调用,这个任务交给 Async 方法去决定。

对异步请求的数据获仍然是由 Action 处理,如 Play 1 中 Action 的各个 await() 方法; Play 2 里的 Action 用 Async 方法。 阅读全文 >>

Play 2.0 中文资料 - Play 缓存 API

默认的 Cache API 实现是用的 EHCache. 你也可以通过插件来提供自己的缓存实现.

访问 Cache API

缓存 API 由 play.api.cache.Cache 对象提供. 它需要注册一个缓存插件.

注: Cache API 尽力保持自身最小化,而允许插入多种实现. 如果你需要一个更具体的 API, 那就通过你自己的缓存插件来使用它.

Unmi 注: EhCachePlugin 的注册方式可以查看 play_x.x.x.jar(比如 $PLAY_HOME/repository/local/play/play_2.9.1/2.0.4/jars/play_2.9.1.jar) 包中的 play.plugins 中的内容:

这是 Play2.0.4 默认注册的插件,其中就包含了 600:play.api.cache.EhCachePlugin 插件。 阅读全文 >>