Table des matières
Play! framework (old page)
The Playframework makes it easier to build Web applications with Java.
Finally a Java framework made by Web developers. Discover a clean alternative to bloated enterprise Java stacks. Play focuses on developer productivity and targets RESTful architectures.
C'est Symfony pour Java ! Ce framework n'est pas basé sur J2EE, il embarque directement sont serveur (Netty).
Discussions:
Tutos & Articles
Recherche des dernières publications sur Play! avec Google.
- Slides de présentation en français
- Développer une application avec le framework Play !. Traduction française du tutoriel officiel de Play Framework visant à créer un moteur de blog (26/01/2010).
- Articles sur la Planet ♥ Play
- Les articles de Peter Hilton et tous ceux de Lunatech research
- Introduction aux webservices REST avec Play! : requêtes REST, sélection du fomat html,xml et json par configuration.
Code snippets:
- Code snippets: You can submit your code snippets here, to share patterns with the community.
Play! Framework cheat sheets:
- The Ultimate PlayCheatSheet (revision 2011-01-02)
Maturité ?
- I don't know for other sites but the playframework website was built with play and serve about 100.000 request by day.
- playframework.org that run on Play 1.1.1 has server 245,923 requests in february without any downtime or errors, and still consume 11Mo of heap. Of course the application itself is very simple but it proves that the framework stack including the HTTP server, has no problems nor memory leaks.
Manque de doc pour:
- Ecrire un Plugin ?
- The Play plug-in is the class that provides access to the Play framework's extension points. PlayPlugin Javadoc
- Ecrire un Module ?
Divers:
… And, with the bytecode vodoo it is doing (injecting code at runtime) …There is no more vodoo things than in any other web framework. For example typical Spring applications do a lot more of magical things at runtime (including dynamic proxy, runtime members injection and AOP generation). In Play there is nothing really resolved at runtime. Everything, including bytecode manipulation, is done at compilation time, and either it works or it fails at compilation time, ie. at start time in production mode.
Tips
Code snippets: You can submit your code snippets here, to share patterns with the community.
unescape #{get 'var' /}
#{set var:'this is " a test'.raw() /}
Configurer Netbeans pour qu'il trouve les sources du Play framework:
In Netbeans: Right click on your project -> Properties -> Java Sources Classpath -> Add Jar/Folder... -> Select the folder <play source code base>/framework/src
How to get the anchor of url in play's controller
Modifier la génération d'application et autre tâches: voir autour de play-framework/resources/application-skel/conf/application.conf
the @{} syntax is meant to generate relative URLs while the @@{} syntax generates absolute ones.
Take a look at the documentation additional details: Actions: @{…} or @@{…}
What does the percentage sign specify in application.conf ?It’s a way to define settings according to a given environment.
When you write “%id.property=value” the “id” refers to a Play! id.
This line will be considered only if you run your application using Play! with id “id”.
See http://www.playframework.org/documentation/1.2/ids for more information.
Templating / Views
Ajouter des styles depuis une vue:
#{set 'moreStyles'}
<link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/xxx.css'}" />
#{/set}
et dans le layout:
<head>
...
#{get 'moreStyles' /}
...
Ajax DataTables
Ajax DataTables with the Play framework: This article is a follow-on to Integrating Play framework with jQuery DataTables, which describes how to integrate DataTables (jQuery plugin) with a Play framework web application. This time, we show how to load the table data from the server using Ajax, rather than decorating an existing (populated) HTML table.
Modules
Tabula Rasa: Tabula Rasa provides support for user-customisable tables, allowing each user to have a custom view of any table in your application. Client-side support is provided using the excellent DataTables jQuery plugin.
Template Engines
Japid
Cambridge
Un moteur de template pour remplacer celui de Play!.
Google Closure
http://www.playframework.org/modules/googleclosure
This module is aimed at integrating Google Closure tools with play!. For the time being, it ONLY provides javascript client templating based on Google Closure Templates.
Tests
- Test Module: The play!framework https://github.com/GuyMograbi/play_test_module will help you write better tests for play!framework applications.
Fetching the response body
In a functional test that uses GET to fetch a JSON response, how does one get the JSON result from the response body?
I have the following in my test:
Http.Response response = GET(request, “/whatever”);
assertIsOk(response);
assertContentType(“application/json”, response);
I know I can use assertContentEquals and assertContentMatch to make assertions about what's in the response body, but how do I fetch that response body itself?
The Http.Response class doesn't seem to have any appropriate method.You can use getContent(response) to extract the response content as String
Models & Data stuff
Binding uploaded Excel to application models, the lazy way (ExcelBinder): Part 1, Part 2
Using persistence out of a Play app
Keep track of record creation/updates: gestion des champs “created_at” et “updated_at” par héritage de classe pour les modèles.
JPA / Hibernate
When using bidirectional relationships in JPA, maintaining consistency between both sides of the relationship for in-memory objects is up to you.
See When is @OneToMany list populated in Play framework ?
What is the proper way to re-attach detached objects in Hibernate ?
Configuration JPA / Hibernate
# Dans conf/application.conf # # Pour voir toutes les requêtes SQL: jpa.debugSQL=true # ou hibernate.show_sql=true # # Hibernate will generate comments inside the SQL, for easier debugging: hibernate.use_sql_comment=true # # statics gathering: hibernate.generate_statistics=true # ### Do not use this, it's bring many problems ! ### quote all database identifiers (Hibernate 3.5+) ## hibernate.globally_quoted_identifiers=true
Bug: counting composite key
La requête SQL générée pour compter des Entity avec une Composite Identity est mal formée:
/* select count(e) from models.CategoryCombinaisonItem e */ select top ? count((categoryco0_."categoryValueId", categoryco0_."categoryId", categoryco0_."categoryCombinaisonId")) as col_0_0_ from "CategoryCombinaisonItem" categoryco0_
La fonction count() ne prend qu'une seule colonne !
En rapport:
It's a Play! bug :
- CategoryCombinaisonItem.count() throw the Exception
- CategoryCombinaisonItem.count(“”) not !
J'ai ouvert le ticket #717.
JPQL "In List" parameter Binding
Je n'arrive pas à Binder un tableau en parameter in(?) du Query JPA
int[] existingValuesId2 ; CategoryValue.delete("category.id = ? and id not in (?)", category.id, //existingValuesId ); // ClassCastException occured : java.util.ArrayList cannot be cast to java.lang.Integer //Arrays.asList(existingValuesId) ); // IllegalArgumentException occured : Parameter value [[7]] was not matching type [java.lang.Integer] //existingValuesId.toArray() ); // ClassCastException occured : [Ljava.lang.Object; cannot be cast to java.lang.Integer //existingValuesId2 ); // (Integer[]) ClassCastException occured : [Ljava.lang.Integer; cannot be cast to java.lang.Integer //existingValuesId2 ); // (int[]) ClassCastException occured : [I cannot be cast to [Ljava.lang.Object; // Obligé de faire une concaténation !!! String existingValuesIdString = ""; for (int i = 0; i < existingValuesId.size(); i++) { existingValuesIdString += (i>0?",":"") + existingValuesId.get(i); } CategoryValue.delete("category.id = ? and id not in (" + existingValuesIdString + ")", category.id);
The solution :
List<Integer> idExs; Exponent.find( "id in (:ids)" ) .bind( "ids", idExs ) .fetch();
Modules
logisima-play-yml: Module to generate yml file from your database
Localisation / Internationalisation
Modules
Messages module
http://www.playframework.org/modules/messages
Module messages provides a web based tool for managing your application’s localizations.
- Forgetting the localizations as you code? This tool will look through your sources and lists the keys that have not been localized yet!
- Forgot to remove the localizations when you refactoring? It also finds keys that are no longer in use and let’s you easily remove them!
- Your messages file is a mess? The messages files are saved in alphabetical order so you can easily add keys to the files manually too!
- Not sure where the key is used? No worries, the tool will show you a snippet from the source code where it found the key!
Conception / Architecture
Declarative model class enhancement in Play: Explain how the @CrudName annotation works (play.classloading.enhancers.Enhancer, play.PlayPlugin).
Page composition / Composite View: il est fréquent pour un site web que les pages soient composées de plusieurs controller/view, par exemple les dernières news à droite, les derniers commits en bas, … Dans Symphony (Php), Tapestry, Wicket, c'est possible. Avec Play! Il n'est pas prévu (et donc déconseillé) de composer une vue à partir de plusieurs controller.
Voir: invoking other controller actions from template (page composition), Using #{include tag to include non-static elements
Update 2011-03-02:
> We'll introduce a very similar concept in a next version of Play (not the 1.2 since I want to release it this month).
> You mean that controller action will only be called from http and the componentes would only be called from the views?
> Yes.
Héritage de Controller. Contoller.parent() is @Deprecated, What to use instead of parent()?. With the current implementation of the Controller layer in Play, controllers inheritance is a bad practice, the controller layer is not object oriented in Play. Well, I'd said that the only usage of controller inheritance (apart extending the Controller class) is to share code between classes. Using inheritance for that is an anti-pattern in general (not only in Play, but in every OO languages).
Appels asynchrones et Jobs
Long query:
Don't forget that the threading model of Play is not the same than a servlet container. You don't need too much database connections for a Play application since it uses a fixed (and generally very low) amount of threads to execute the requests.
Basically if your applications uses 3 threads, then 3 database connections are enough.Sure the thread model is better, but if I serve 5 user per second, and the request takes 6 seconds in database access, with only three connections users must wait for free connections.If your DB-Queries take 6 seconds, you should probably think of doing them in a job and use suspendable request feature of play.
How can I keep track of a job progress ?
Appels asynchrones avec Play Framework: Démonstration d'une classe qui va permettre d’“écouter” les modifications et de “notifier” les abonnés lorsqu’une modification a lieu.
Le Jobs Status de felipera (googlegroup post).
Securité
Cross Site Request Forgery (CSRF)
Play génère automatiquement un token qu'il mets dans les forms générées avec le tag #{form} … Mais il ne vérifie pas ce token automatiquement ! Il faut le faire explicitement.
Il faut lire cet article pour appréhender toute la porter de la protection CSRF à implémenter avec Play : Play Framework Security: Fighting Cross Site Request Forgery
Control d'accès
User's role: If each user only has a single role, then the Secure module is what you need. I can't really add more than what's detailed in http://www.playframework.org/documentation/1.1.1/secure and http://www.playframework.org/documentation/1.1.1/guide8 - these cover everything you need, and the example code of yabe can be used as a guide. If each user can have more than one role, consider the deadbolt module this allows you to and, or and not role combinations in your security restrictions.
deadbolt module
How can I implement multiple user roles in Play!, with each having role-specific permissions and views, and what would be an appropriated database scheme?Use the deadbolt module !
I've just released Deadbolt 1.3 in order to provide arbitrary security on named resources at the method, class or view level. You can now have resources which are entirely locked by the RestrictedResource annotation, or allow a fallback to the static authorisation of Restrict and Restrictions.
@With(Deadbolt.class) public class MyController extends Controller { @RestrictedResource(name="foo") public static void list() { // depending } @RestrictedResource(name="bar", staticFallback=true) @Restrict("cheese") public static void delete() { } }
Determining access is done via RestrictedResourcesHandler instances which are provided to Deadbolt via the DeadboltHandler. This means you can have various types of RestrictedResourcesHandlers based on, again, arbitrary decisions.
Autres modules
CAS authentification module (SSO):
Performance
Press
The press module is a JavaScript and CSS minimizer that is designed to be transparent to the application developer: Simply replace <script> tags with #{press.script} tags, and <link rel=“stylesheet”> tags with #{press.stylesheet} tags.
greenscript
http://www.playframework.org/modules/greenscript, http://github.com/greenlaw110/greenscript
Minimize javascript/css files [greenscript] module:
- compress and merge (configurable)
- cache minimized files (configurable)
- js/css dependency management (configurable)
- support runtime configuration (minimize/caching/dependencies)
- simplest tag syntax: #{js ‘js1 js2’ /}
- inline dependency declaration: #{greenscript.js ‘app < lib < jquery’/}
- transparent compression zero configuration
- support CDN
- support inline js/css body
- support resource and dependency management in modules
Déploiement
Deploy and running Play! without the source code ?Use the 'precompile' command. Then you could deploy the application without the app/ folder.
Serving several appsPlay applications usually run on a dedicated VM. You can generate WAR files and deploy them into a classical JEE application servers, but it's not optimal. For me running 50 JVM on a server with 16GB of RAM is ok. — Guillaume Bort 28/02/2011
Amazon EC2I'm using a micro EC2 instance to run Play! website with few traffic. I'm using nginx and PostgreSQL in the same micro instance, and all works ok.
The only problem is when you start the Play! application in production mode. Because, when Play! start to compile all classes and views, the instance becomes to be very unstable due to high load CPU (if you see the documentation about how works an EC2 micro instance, you will understand this point better). To avoid this, you can precompile the application locally, upload precompiled/ directory to EC2 instance, and start the application with -Dprecomplied=true.
Start/Stop script
start: "play start" - this will run play in background and put a pid file in the current folder stop: "play stop" - this will get the pid file and stop the play process and then remove the pid file