Play libs
The play.libs package contains several useful libraries that will help you to achieve common programming tasks.
Most of these libraries are simple helpers that are really straightforward to use:
- Codec: Utilities to encode and decode data.
- Crypto: Cryptographics utilities.
- Expression: Evaluate dynamic expressions.
- F: Functional programming with Java.
- Files: File system manipulation helpers.
- I18N: Internationalization helpers.
- IO: Stream manipulation helpers.
- Images: Image manipulation utilities.
- Mail: E-mail functions.
- MimeTypes: Dealing with MIME types.
- OAuth: OAuth client protocol.
- OAuth2: OAuth2 client protocol.
- OpenID: OpenID client protocol.
- Time: Time and duration utilities.
- WS: Powerful Web Service client.
- XML: Loading XML structures.
- XPath: Parsing XML using XPath.
The following sections provide more information about the most important libraries.
Parsing XML using XPath
XPath is probably the easiest way to parse an XML document without having to use code generation tools. The play.libs.XPath library offers all the needed primitives to efficiently achieve this task.
The XPath operations operate on all org.w3.dom.Node types:
org.w3.dom.Document xmlDoc = … // retrieve a Document somewhere
for(Node event: XPath.selectNodes("events//event", xmlDoc)) {
String name = XPath.selectText("name", event);
String data = XPath.selectText("@date", event);
for(Node place: XPath.selectNodes("//place", event)) {
String place = XPath.selectText("@city", place);
…
}
…
}
Web Service client
The play.libs.WS provides a powerful HTTP client. Under the hood it uses Async HTTP client.
Making a request is easy:
HttpResponse res = WS.url("http://www.google.com").get();
Once you have an HttpResponse object you can access all the response properties.
int status = res.getStatus();
String type = res.getContentType();
You can also retrieve the body content in several content types:
String content = res.getString();
Document xml = res.getXml();
JsonElement json = res.getJson();
InputStream is = res.getStream();
You can also use the async API to make HTTP requests in a non-blocking way. Then you will receive a Promise<HttpResponse>. Once redeemed, you can use the HttpResponse as usual:
Promise<HttpResponse> futureResponse = WS.url(
"http://www.google.com"
).getAsync();
Functional programming with Java
The play.libs.F library provide several useful constructs coming from functional programming. These constructs are used to handle complex abstraction cases. For those that are accustomed to functional programming we provide:
Option<T>(a T value that can be or not set)Either<A,B>(contains either a A value or a B value)Tuple<A,B>(contains both A and B values)
Promises
A Promise is Play’s custom Future type. In fact a Promise<T> is also a Future<T> so you can use it as a standard Future. But it has also a very interesting property: the ability to register callback usingonRedeem(…) that will be called as soon as the promised value is available.
Promises are used everywhere in Play in place of Future (for Jobs, WS.async, etc…).
Promises can be combined in several ways. For example:
Promise p = Promise.waitAll(p1, p2, p3)
Promise p = Promise.waitAny(p1, p2, p3)
Promise p = Promise.waitEither(p1, p2, p3)
Pattern Matching
Sometimes we feel that we need pattern matching in Java. Unfortunately Java does not have built-in pattern matching, and because of the lack of functional constructs, it is difficult to add it as a library. Anyway we’ve worked on a solution that is not so bad.
Our idea was to use the latest ‘for loop’ syntax to achieve basic pattern matching for Java. Pattern matching must both check if your object matches the required conditions and extract the interesting value. The Pattern matching library for Play is part of the play.libs.F library.
Let’s see a simple example; you have a reference of type Object and you want to check that it is a string that starts by “command:”.
The standard way would be:
Object o = anything();
if(o instanceof String && ((String)o).startsWith("command:")) {
String s = (String)o;
System.out.println(s.toUpperCase());
}
Using the Play pattern matching library, you can write it as:
for(String s: String.and(StartsWith("command:")).match(o)) {
System.out.println(s.toUpperCase());
}
The for loop is executed once, only if the condition is met, and it automatically extracts the String value without the need for casting. Because there is no explicit cast, everything is type-safe, and checked by the compiler.
OAuth
OAuth is an open protocol for secure API authorization, using a simple and standard approach, from desktop and web applications.
Two different specifications exist: OAuth 1.0 and OAuth 2.0. Play provides libraries to connect as a consumer to services proposing either of these specifications.
The general process is the following:
- Redirect the user to the provider’s authorization page
- After the user grants authorization, he is redirected back to your server along with an unauthorized token
- Your server exchanges the unauthorized token with an access token specific to the current user, that needs to be saved in order to perform requests to the service. This step is done as server-to-server communication.
The Play framework takes care of most of the process.
OAuth 1.0
The OAuth 1.0 functionality is provided by the play.libs.OAuth class and is based on oauth-signpost. It is used by services such as Twitter or Google
To connect to a service, you need the create a OAuth.ServiceInfo instance using the
following information, obtained from the service provider:
- Request token URL
- Access token URL
- Authorize URL
- Consumer key
- Consumer secret
The access token can be retrieved this way:
public static void authenticate() {
// TWITTER is a OAuth.ServiceInfo object
// getUser() is a method returning the current user
if (OAuth.isVerifierResponse()) {
// We got the verifier;
// now get the access tokens using the unauthorized tokens
TokenPair tokens = OAuth.service(TWITTER).requestAccessToken(
getUser().getTokenPair()
);
// let's store them and go back to index
getUser().setTokenPair(tokens);
index();
}
OAuth twitt = OAuth.service(TWITTER);
TokenPair tokens = twitt.requestUnauthorizedToken();
// We received the unauthorized tokens
// we need to store them before continuing
getUser().setTokenPair(tokens);
// Redirect the user to the authorization page
redirect(twitt.redirectUrl(tokens));
}
Calls can now be done by signing the requests using the token pair:
mentions = WS.url(url).oauth(TWITTER, getUser().getTokenPair()).get().getString();
The full example usage is available in samples-and-tests/twitter-oauth.
OAuth 2.0
OAuth 2.0 is much simpler than OAuth 1.0 because it doesn’t involve signing requests. It is used byFacebook and 37signals.
Functionality is provided by play.libs.OAuth2.
To connect to a service, you need the create a OAuth2 instance using the following information, obtained from the service provider:
- Access token URL
- Authorize URL
- Client ID
- Secret
public static void auth() {
// FACEBOOK is a OAuth2 object
if (OAuth2.isCodeResponse()) {
String access_token = FACEBOOK.getAccessToken();
// Save access_token, you will need it to request the service
index();
}
FACEBOOK.requestAccessToken(); // This will trigger a redirect
}
Once you have the access token associated to the current user, you can use it to query the service on behalf of the user:
WS.url(
"https://graph.facebook.com/me?access_token=%s", access_token
).get().getJson();
The full example usage is available in samples-and-tests/facebook-oauth2.
OpenID
OpenID is an open and decentralized identity system. You can easily accept new users in your application without having to keep specific user information. You just have to keep track of authorized users through their OpenID.
This example provides a high-level view of how OpenID authentication can be used within a Play application:
- For each request, check if the user is connected
- If not, display a page where the user can submit his OpenID
- Redirect the user to the OpenID provider
- When the user comes back, get the verified OpenID and save it in the HTTP session.
The OpenID functionality is provided by the play.libs.OpenID class.
@Before(unless={"login", "authenticate"})
static void checkAuthenticated() {
if(!session.contains("user")) {
login();
}
}
public static void index() {
render("Hello %s!", session.get("user"));
}
public static void login() {
render();
}
public static void authenticate(String user) {
if(OpenID.isAuthenticationResponse()) {
UserInfo verifiedUser = OpenID.getVerifiedID();
if(verifiedUser == null) {
flash.error("Oops. Authentication has failed");
login();
}
session.put("user", verifiedUser.id);
index();
} else {
if(!OpenID.id(user).verify()) { // will redirect the user
flash.error("Cannot verify your OpenID");
login();
}
}
}
And the login.html template:
#{if flash.error}
<h1>${flash.error}</h1>
#{/if}
<form action="@{Application.authenticate()}" method="POST">
<label for="user">What’s your OpenID?</label>
<input type="text" name="user" id="user" />
<input type="submit" value="login..." />
</form>
</code>
And finally the routes definitions:
GET / Application.index
GET /login Application.login
* /authenticate Application.authenticate
Continuing the discussion
Now we’ll check how to perform operations outside any HTTP request using Ansynchronous Jobs.
Play libs的更多相关文章
- 编译gtk+程序报错gcc: pkg-config --cflags --libs gtk+-2.0: 没有那个文件或目录
第一次接触gtk+.在网上搜罗良一番,装好相应的库后,编写了第一hello程序.在编译时输入以下命令:gcc -o hello hello.c 'pkg-config --cflags --libs ...
- Android中libs目录下armeabi和armeabi-v7a的区别
armeabi默认选项,支持基于 ARM* v5TE 的设备支持软浮点运算(不支持硬件辅助的浮点计算)支持所有 ARM* 设备 armeabi-v7a支持基于 ARM* v7 的设备支持硬件 FPU ...
- python INFO: Can't locate Tcl/Tk libs and/or headers
安装opencv的时候遇到这个错误: python INFO: Can't locate Tcl/Tk libs and/or headers 参考如下文章解决这个问题: http://www.ver ...
- 如何为libs目录下的jar包关联源代码
以前,我们可以为lib目录下的jar包关联源代码,但是现在似乎不行了. 下面是一篇讲述此问题解决方法的文章: How to attach javadoc or sources to jars in l ...
- Makefile选项CFLAGS,LDFLAGS,LIBS
CFLAGS 表示用于 C 编译器的选项, CXXFLAGS 表示用于 C++ 编译器的选项.这两个变量实际上涵盖了编译和汇编两个步骤. CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS ...
- Android studio libs目录
Android studio libs目录: 关于Android studio libs目录,Android studio 已经为我们自动生成了,如果默认 是看不到默认Libs目录的,点击红色按钮地方 ...
- 写你自己 android 多通道打包工具 可以包libs和.so文件
android上传应用程序,需要区分各个信道. 通常更改配置文件中的一个通道id,假设有多个通道,手动更改并生成apk这将是非常麻烦的,及增加误差的概率. 在这个课堂上分享一个打包工具.也可在网上类似 ...
- Gentoo: !!! existing preserved libs问题
问题描述 !!! existing preserved libs: >>> package: media-libs/libmng-2.0.2-r1 * - /usr/lib/libm ...
- 用AndroidStudio发布Libs到Bintray jCenter
1 RootProject[根目录]build.gradle中添加如下插件引用 dependencies { ....... classpath 'com.jfrog.bintray.gradle:g ...
随机推荐
- java容器详细解析
前言:在java开发中我们肯定会大量的使用集合,在这里我将总结常见的集合类,每个集合类的优点和缺点,以便我们能更好的使用集合.下面我用一幅图来表示 其中淡绿色的表示接口,红色的表示我们经常使用的类. ...
- struts2拦截器
一.自定义拦截器 struts2拦截器类似于servlet过滤器 首先定义一个拦截器这个拦截器实现了Interceptor接口: package cn.orlion.interceptor; impo ...
- oc连接signalr,各种填坑
在网上搜了signalr的oc客户端,基本上都指向同一个东西https://github.com/DyKnow/SignalR-ObjC 但是这个也有日子没更新了,用cocoapods安装下来是编译不 ...
- Request 接收参数乱码原理解析一:服务器端解码原理
“Server.UrlDecode(Server.UrlEncode("北京")) == “北京””,先用UrlEncode编码然后用UrlDecode解码,这条语句永远为true ...
- Cocos2d-x 3.2 学习笔记(四)学习打包Android平台APK!
从cocos2dx 3.2项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后,以后就会非常快捷! (涉及到3.1.1版本的,请自动对应3.2版本,3.x版本的环境搭建都是一样的) ...
- Linux的学习--crontab
之前了解过一点crontab,前段时间比较闲,就熟悉了一下,今天总结记录一下. crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并 ...
- JavaScript的学习--JavaScript设计模式的总结
这篇博客只是自己对设计模式的理解的备忘~ 看完了<JavaScript设计模式>这本书,一直没有写博客记录一下,最近抽出时间来重读了一下,就顺便记录一下~ 如果你只是想粗略了解一下Java ...
- 借助 CSS Colorguard 来避免使用重复的颜色
每一个 CSS 项目开始时愿望都是很美好的,但不可避免地,多人协作的项目相互之间可能重复使用了相似的颜色,而你从来不知道它们的存在.CSS Colorguard 帮助您保持您想要的颜色设置,当你添加的 ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】
<Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...
- SQL Server 2014里的缓存池扩展
在今天的文章里我想谈下SQL Server 2014里引入的缓存池扩展(Buffer Pool Extensions).我们都知道,在SQL Server里,缓存池是主要的内存消耗者.当你从你存储里读 ...