Controller.action – Smart binding
Controller/link?i=32&n=patrick
public static void link(int i, String n)
public static void link(Integer i, String n)
public static void link(Long i, String n)
Controller/show?id[0]=1&id[1]=2&id[2]=3&id[3]=4
public static void show(Long[] id)
public static void show(List
public static void show(Set
Controller/get?date=02-18-1972
public static void get(@As("MM-dd-yyyy") Date date)
(@As(binder=MyCustomStringBinder.class))
Custom parameter binder
public static void create(String comment, File attachment)
Send File as multipart/form-data encoded POST request
[email protected]
public static void create(Client client)
JavaBean (POJO) binding
@NoBinding
Marks a non-bindable field
Controller.action – Validation
@Required String lastname
@IsTrue String agree
@Max(7500) Integer wordCount
@Min(18) Long age
@MaxSize(2083) String value
@MinSize(42) String value
@Email String address
@Equals("passwordConfirmation") String password
@InFuture String dueDate
@InFuture("1979-12-31") String birthDate
@Match("[A-Z]{3}") String abbreviation
@Match("(directDebit|creditCard|onReceipt)")
@Past String actualDepartureDate
@Past("1980-01-01") String birthDate
@Range(min = 17500, max = 40000) String wordCount
@URL String address
@IPv4Address String ip
@IPv6Address String ip
@Phone String phone
Relaxed phone validation
@Valid Person person
JavaBean (POJO) validation – class Person needs validation annotations
Controller – Session Management
WARNING: Play Session is NOT the J2EE session
session and flash use cookies! 4KB limit/20 cookies max
session.getId();
Returns the session ID – in most cases: a must have!
session.put(String key, String value);
session.get(“user_flag”);
Values are limited to Strings, 4KB max
flash.put(String key, String value);
flash.get(String key);
Flash entries are discarded at end of next request
Cache.set(“key_” + id, product, “30mn”);
Set cache value to 30 minutes
Cache.get(“key_” + id, Product.class);
Get cache value, may return null
Cache.delete(“key_” + id);
Non blocking cache delete
Cache.safeDelete(“key_” + id);
Blocking cache delete
Controller.action – Redirection
render(params...);
Renders template with given parameters, as text/html
renderXML(params...);
Renders parameters as application/xml
renderJson(params...);
Renders parameters as application/json
renderText(params...);
Renders parameters as text/plain
renderTemplate(“Clients/showClient.html”, id, client);
Bypasses default template
redirect(“http://www.crionics.com”);
HTTP redirect to the given URL
From an action, calling another Controller.action()
The framework transparently generates a REDIRECT!
Controller – Jobs
@OnApplicationStart
@On("0 0 12 ∗ ∗ ?")
Every day at 12:01pm
@On("10 30 12 ? ∗ MON-FRI")
Every working day at 12:30pm and 10s
@Every("1h")
public class Bootstrap extends Job {public void doJob() {...} }
Controller – Interceptions
@Before ➟ action ➟ @After ➟ template ➟ @Finally
Interceptions evaluation order
@Before static void checkAuthentification()
@After static void log()
@Finally static void audit()
You get the idea
@With(Secure.class)
public class Admin extends Application
Custom interceptors at the controller scope
@Catch(value={RuntimeException.class})
public static void onException(RuntimeException e) {…}
Exception handling at the controller level
Controller.action – Others
Logger.info("Action executed ...");
Logger.debug("A log message");
Logger.error(ex, "Oops");
Logging configuration lives in application.conf
@CacheFor("1h") public static void index() { ... }
Caches the result of the action for 1 hour
Play.configuration.getProperty("blog.title");
Access to the configuration file
Query query = JPA.em().createQuery("query");
Access the persistence manager
Controller – Libraries
WS.url("http://s.com/posts").get().toJSON();
HTTP GET request to JSON
WS.url("http://s.com/").post().toXML();
HTTP POST request to XML
DB.execute("raw sql");
Eval raw SQL
XML.getDocument(String);
String to XML
XML.serialize(Document);
XML to String
XPath.selectNodes(String xpath, Object node);
XPath expression evaluator
Files.copy(File,File);
File copy
Files.copyDir(File,File);
Recursive directory copy
Files.delete(File);
Files.deleteDirectory(File);
Deletes file/directory
IO.readLines(File);
IO.readContentAsString(File);
IO.readContent(File);
IO.write(byte[],File);
Read/Write file contents
Images.crop(File orig,File to, int x1, int y1, int x2, int y2);
Images.resize(File orig, File to, int w, int h);
Images.toBase64(File image);
Handy methods!
Crypto.encryptAES(String);
Crypto.decryptAES(String);
Encryption using the application secret key
Crypto.passwordHash(String);
Create an MD5 password hash
Codec.UUID();
Generates unique IDs
Codec.byteToHexString(byte[] bytes);
Write a byte array as hexadecimal String
Codec.encodeBASE64(byte[] value);
Codec.decodeBASE64(String base64);
Encode/Decode a base64 value
Codec.hexSHA1(String);
Build a hexadecimal SHA1 hash for a String