Aujourd'hui nous allons effectuer l'opération inverse, l'envoi d'un contenu XML au contrôleur Play!, à travers une URL RESTful.
On veut par exemple envoyer le contenu suivant en POST avec un content type application/xml :
<album>
<artist>Metallica</artist>
<name>Death Magnetic</name>
<release-date>2008</release-date>
<genre>METAL</genre>
</album>
Pour cela on ajoute la ligne suivante au fichier routes pour autoriser l'opération POST sur l'url /album :
POST /album Application.saveXml
La méthode saveXml récupère le contenu de la requete dans la variable request.body.
Elle parse ensuite le contenu pour créer un album et l'enregistrer dans la base. La classe play.libs.XPath facilite le parcours de documents XML :
public static void saveXML(){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = null;
try{
//création du document XML à partir de la requête
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(request.body);
}
catch(Exception e){
}
//parsing du contenu XML
Element albumNode = document.getDocumentElement();
//Artiste
String artistName = XPath.selectText("artist",albumNode);
Artist artist = new Artist(artistName);
//get the name
String albumName = XPath.selectText("name", albumNode);
Album album = new Album(albumName);
//get the date
String date = XPath.selectText("release-date",albumNode);
DateFormat dateFormat = new SimpleDateFormat("yyyy");
try {
album.releaseDate = dateFormat.parse(date);
} catch (ParseException e) {
Logger.error(e.getMessage());
}
//genre
String genre = XPath.selectText("genre", albumNode);
Genre genreEnum = Genre.valueOf(genre.toString().toUpperCase());
album.genre = genreEnum;
//sauvegarde
album.artist = artist;
album.save();
}
NB: il est bien sûr possible d'obtenir un code moins verbeux en dé-sérialisant l'objet à l'aide d'un outil comme JAXB ou XStream, mais ce n'est pas l'objet de ce billet.
Lorsqu'on écrit le code album.artist=artist, la méthode setArtist(Artist artist) est appelée automatiquement par Play! (le code est modifié au runtime). On peut ainsi vérifier le fait que l'artiste existe ou non dans la base, pour savoir si on doit créer une nouvelle instance d'artiste ou récupérer l'artiste existant.
La méthode save() de la classe Album s'occupe alors d'enregistrer l'album en base, ainsi que l'artiste si il est inconnu dans la bibliothèque(à l'aide d'un cascade JPA).
public void setArtist(Artist artist){
List<artist> existingArtists = Artist.find("byName", artist.name).fetch();
if(existingArtists.size()>0){
//Le nom d'artiste est unique
this.artist=existingArtists.get(0);
}
else{
this.artist=artist;
}
}
Notre API REST/XML nous permet donc maintenant de lire la liste des albums de note bibiothèque musicale et d'ajouter des albums.
Vous pouvez tester l'envoi de contenu XML avec le plugin Poster de Firefox (la démarche est expliquée dans ce billet) ou avec l'application rest-client.
Un autre post si vous désirez continuer : Play framework : exporter ses objets en JSON
0 commentaires:
Enregistrer un commentaire