mardi 29 septembre 2009

Sitebricks : le nouveau framework web de Google

Google lancera bientôt son nouveau framework web : Sitebricks. Ce nouvel outil, construit sur le framework d'injection de dépendances Guice, se veut simple et intuitif, ce qui n'a rien d'étonnant quand on connait la philosophie de Google. Sitebricks propose un système de templates basés sur un mélange de HTML et d'annotations, avec un système de binding vers des beans Java, le tout en s'inspirant du fonctionnement des services Restful!

Petit exemple :
  • On définit une méthode d'accès à une liste de personnes avec les annotation @At et @Get dans un POJO :


@At("/persons")
public class PersonPage {
private List<Person> persons;

@Get
public void get() {
this.persons = personsDao.getPersons();
}
}

  • On accède aux données de ce POJO via le template html :



    @Repeat(items=persons, var="person")
  • ${person.name}



L'annotation @Repeat permet d'itérer sur la collection de personnes pour afficher leur nom, en affichant autant de balises <li> qu'il y a d'éléments.
D'autres annotations sont disponibles, comme @ShowIf qui permet de définir une collection pour afficher ou nom un composant (en fait une balise et son contenu). Pour des besoins spécifiques il sera également possible de développer ses propres annotations, ou "bricks" (un peu comme pour les tag libs JSP).

Dans le sens inverse, pour envoyer des données depuis un formulaire vers un POJO, on utilise une annotation POST :


private Person newPerson;
@Post
public void postPerson() {
personDAO.save(newPerson);
}


Et on "binde" les champs simplement en définissant un nom correspondant aux champs des objets Java :


<input name="newPerson.name" type="text">



L'objet newPerson sera automatiquement rempli avec les valeurs du formulaire html (il faut bien sur définir les getters et setters pour cet objet).

Pour aller plus loin

  • Ajouter des paramètres pour accéder aux ressources

Sitebricks tire parti du style Restful en proposant un moyen plus élaboré de récupérer des ressources:



@At("/persons/town/:town")
public class PersonPage{

@Get
public void get(@Named("town") String town) {
personDao.gePersonstByTown(town);
}

On pourra ainsi récupérer la liste des personnes d'une ville spécifique avec le code suivant dans le template :





    @Repeat(items=persons/town/Paris, var="person")
  • ${person.name}


  • Réutilisation de composants

Sitebricks possède également un mécanisme permettant de faciliter la réutilisation de composants. Un fragment de page ou "brick" peut être annoté comme "imbriquable" dans une autre page en ajoutant l'annotation "@EmbedAs" dans le POJO correspondant au fragement.

Par exemple ce fragment affiche un message :

@EmbedAs"HelloBrick"
public class Hello{
private String message;
...
}


$message


L'insertion se fait alors simplement dans le code html en rappelant le fragment par une annotation du même nom :



...
@HelloBrick(message="coucou")





Si cette introduction vous a mis l'eau à la bouche, vous pouvez suivre le projet sur cette page : http://code.google.com/p/google-sitebricks/
Vous aurez ainsi toutes les informations nécessaires pour mettre en place et configurer le framework.

En conclusion je trouve ce framework assez sympathique, on sent que l'accent a été mis sur la légereté et la simplicité. De plus, l'orientation Restful du framework est une approche qui me parait originale et dans l'air du temps.
Et vous qu'en pensez vous? Sitebricks pourra-t-il s'imposer et remplacer le vieillissant Struts ou encore JSF dans le coeur des développeurs?

mercredi 23 septembre 2009

Génération d'une appli JEE 6 avec NetBeans

Le développement d'applications de gestion contient son petit lot des taches répétitives, demandant peu de réflexion : création des formulaires, persistance et récupération des données... En tant que développeurs, nous rêvons souvent de pouvoir automatiser ces étapes peu intéressantes pour nous concentrer sur le vrai code métier de notre application, celui qui nécessite réellement l'apport d'une intelligence humaine.
Pour cela, nous pouvons utiliser des frameworks de RAD, comme Spring ROO ou Grails.
Nous allons voir aujourd'hui une autre alternative, la génération de code sous NetBeans à partir du modèle objet.
Cette méthode permet de générer une application JEE 6 à base de JSF 2.0 et EJB 3.1 à partir d'entités JPA 2.0, en utilisant l'outil JsfCrudGenerator de NetBeans 6.8 (qui est encore pour le moment en version beta). Attention à bien télécharger la version "Java" pour bénéficier du serveur GlassFish v3, dont nous aurons besoin dans la suite du tutoriel.

La première étape consiste à définir son modèle objet. Nous allons utiliser au maximum les wizard de NetBeans pour avoir le moins de code possible à taper.
Après avoir créé un projet de type Web Application dans NetBeans en ayant coché l'option Java Server Faces, créer les entités du domaine métier depuis le menu "New-->Entity Class" :




Lors de la création de la première entité, cliquer sur "Create Persistence Unit",cocher l'option "Table Generation Strategy : create" et choisir un des datasources proposés :



Au runtime, une base de données Derby sera automatiquement créée sur le serveur Glassfish livré avec NetBeans.

Une fois les entités créées, utiliser le wizard "New-->JSF Pages from entities Classes", juste au dessus de l'option Entity Class.
A partir du wizard, sélectionnez toutes les entités :


Suivez le wizard, et voilà votre application est créée! Vous pouvez la tester en effectuant un clic droit sur le projet et en cliquant sur "Run".

  • Exemples d'écrans :
Lister des entités

Modifier une entité


Vous comme pouvez le constater, cette méthode a l'avantage de faire gagner énormément de temps sur l'écriture des pages JSF, des contrôleurs et des EJB. Cependant elle n'est pas exempte de défauts : le code généré n'est pas très agréable à lire et à maintenir, notamment lorsqu'il fait appels aux fonctions "jsf_crud" dans les pages JSF... De plus, il ne faut pas espérer obtenir une application livrable en l'état, comme vous pouvez le constater il s'agit surtout de pré-macher le travail pour gagner du temps, les pages web générées étant assez rudimentaires.

lundi 21 septembre 2009

Blog en transition

Le blog est actuellement en transition, en effet il sera bientôt redirigé vers un nouveau nom de domaine : coffeebean.loicdescotte.com

En attendant l'ancienne url fonctionne toujours, cependant vous pouvez rencontrer quelques problèmes techniques notamment pour sousrcire au flux RSS. Pour accéder au flux vous pouvez passer par l'url feedburner qui elle fonctionne toujours : http://feeds2.feedburner.com/blogspot/IUKF

A bientôt sur coffeebean.loicdescotte.com !

Edit du 22/09 à 14:00 : tout fonctionne normalement maintenant!

samedi 19 septembre 2009

Un widget Deezer sur le blog

Bonjour à tous,
juste un petit billet pour vous dire que j'ai ajouté un petit widget Deezer sur le blog, ainsi vous pourrez lire les billets en musique et de mon côté je pourrai partager mes dernières trouvailles musicales!
Sur ce, je vous souhaite un bon week end!

mercredi 16 septembre 2009

Nouveautés JPA 2 : Gestion des collections

Vous connaissez certainement JPA, l'api de persistence des objets Java introduite avec Java EE 5.
Avec l'arrivée de la norme JEE 6, JPA dévoile sa version 2.0.
Nous allons voir ensemble les nouveautés apportées par cette nouvelle version.
Pour ceux qui ne sont pas encore familiarisés avec JPA 1er du nom, je vous conseille la lecture de ce tutoriel.

A l'aide de nouvelles annotations, JPA 2 offre de nouvelles manières de mapper et de persister les collections.

@ElementCollection

L'annotation ElementCollection offre des facilités pour la persistence des listes de types primitifs ou de types de base de Java comme Integer ou String.
Auparavant, pour persister une liste de String par exemple, il était nécessaire de persister sous forme de Blob un objet sérialisé contenant les valeurs à enregistrer, cet objet pouvant être une ArrayList ou un HashSet par exemple . Le "probleme" venant du fait que le type String n'étant pas une entité JPA, il ne pouvait être mappé avec un traditionnel @ManyToOne ou @ManyToMany. Un autre contournement possible était de créer une entité JPA comprenant uniquement le String à persister entant qu'attribut et éventuellement une clé technique. Créer une telle table parait logique si on analyse le problème d'un point de vue relationnel, par contre d'un point de vue objet il est dommage d'avoir à s'encombrer d'une telle classe.
Heureusement avec JPA 2 et l'annotation ElementCollection , ce genre de mapping devient beaucoup plus naturel.

Cette annotation s'utilise comme ceci :
@ElementCollection
@CollectionTable(name = "nom")
@Column(name = "value")
List<String> noms;


En utilisant cette annotation, une table comprenant une clé technique + la valeur à enregistrer pour chaque String sera créee automatiquement et utilisée de manière transparente. JPA fait donc bien son travail : s'occuper des problématiques de stockage des données dans le modèle relationnel, en laissant le développeur créer un modèle cohérent d'un point de vue objet.

L'annotation Column permet de spécifier le nom de la colonne qui contiendra les valeurs (des String dans notre exemple) à persister.
Enfin, l'annotation CollectionTable permet de spécifier le nom de la table à générer pour stocker ces valeurs.

Les annotation Column et CollectionTable sont optionnelles, si elles ne sont pas présentes des valeurs par défauts seront utilisées pour les noms de tables et de colonnes.

Et pour les Maps ?

Si l'on désire persister une Map, l'annotation MapKeyColumn permet de spécifier le nom de la colonne qui contient la clé de la Map . On mappe ici des numéros de mois avec le nom du mois , par exemple (3,"Mars") :
@ElementCollection
@CollectionTable(name="track")
@MapKeyColumn (name = "monthNumber")
@Column(name = "month")
private Map<Integer,String> months;

Orphan removal

L'option orphanRemoval a été ajoutée aux annotations @OneToMany et @OneToOne.
Ainsi si un objet anciennement référencé comme lié à votre entité n'est plus attachée à celle ci, il sera supprimé de la base. Ceci évite donc d'avoir des données orphelines qui trainent dans la base. Cela n'est malheureusement pas possible pour les liens de type ManyToMany et ManyToOne car l'ORM ne peut pas savoir après suppression d'un lien si l'ancien objet lié n'est pas référencé par un autre objet sans lancer une requête.

Order column

Enfin, la dernière annotation que nous allons voir aujourd'hui : @OrderColumn permet de spécifier pour une collection d'entités une colonne de tri, pour la lecture et pour l'écriture.
Ainsi au moment de persister la collection, un tri sera effectué pour que les données soient ordonnées en base selon ce critère. Lors de la lecture, un simple "order by" sera utilisé pour ramener les données dans l'ordre souhaité.
Par exemple on trie ici les livres d'une bibliothèque en fonction de leur titre :
@Entity
public class Bibilotheque {
@Id int id;
@ManyToMany
@OrderColumn(name="titre")
List<Livre> livres;
}