ROME – Intégration avec une Servlet (7/8)
Dans cet exemple nous créons une servlet qui renvoie un flux en réponse. Le type de flux voulu peut être passé en paramètre d’URL de la requête. Dans cet exemple les entrées du flux sont écrites en dur, mais il serait tout aussi simple de les générer dynamiquement (depuis une base de données par exemple).
Le coeur de la servlet FeedServlet est ce bout de code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class FeedServlet extends HttpServlet { ... public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException { ... SyndFeed feed = getFeed (req); String feedType = req.getParameter (FEED_TYPE); feedType = (feedType != null) ? feedType : _defaultFeedType; feed.setFeedType (feedType); res.setContentType (MIME_TYPE); SyndFeedOutput output = new SyndFeedOutput (); output.output (feed, res.getWriter ()); ... } // doGet () protected SyndFeed getFeed (HttpServletRequest req) throws IOException,FeedException { SyndFeed feed = new SyndFeedImpl (); ... // Ajout des entrées et des informations sur le flux. return feed; } // getFeed () } // FeedServlet |
La servlet renvoie le flux lors d’une requête HTTP GET avec l’appel à la méthode doGet ().
Pour commencer on récupère l’objet SyndFeed en appelant la méthode getFeed (), on passe l’objet de la requête qui pourrait contenir des informations contextuelles pour créer le flux. La création d’un flux grâce à la classe SyndFeed est expliquée en détail dans le tutorial Écriture d’un flux.
Ensuite on détermine le type de flux souhaité en regardant le paramètre de la requête, si celui-ci n’est pas précisé on choisi un type par défaut (spécifié par un paramètre d’initialisation de la servlet).
Enfin, la réponse est renvoyée avec le bon Content-Type (l’objet constant MIME_TYPE a pour valeur ‘application/xml; charset=UTF-8′) et le flux est écrit en utilisant la classea SyndFeedOutput.
Voici le code complet de la servlet :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | package com.mkhelif.rome.exemples; import com.sun.syndication.feed.synd.*; import com.sun.syndication.io.FeedException; import com.sun.syndication.io.SyndFeedOutput; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; /** * Exemple d'une Servlet qui renvoie un flux crée avec ROME. * * Le type de flux est choisi en fonction du paramètre 'type' de la requête, si le paramètre est manquant * on prend la valeur du paramètre d'initialisation de la servlet 'default.feed.type', si se paramètre est manquant, on choisi par * défaut 'atom_0.3'. * * @author Marwan KHELIF */ public class FeedServlet extends HttpServlet { private static final String DEFAULT_FEED_TYPE = "default.feed.type"; private static final String FEED_TYPE = "type"; private static final String MIME_TYPE = "application/xml; charset=UTF-8"; private static final String COULD_NOT_GENERATE_FEED_ERROR = "Impossible de générer le flux"; private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd"); private String _defaultFeedType; public void init () { _defaultFeedType = getServletConfig ().getInitParameter (DEFAULT_FEED_TYPE); _defaultFeedType = (_defaultFeedType != null) ? _defaultFeedType : "atom_0.3"; } // init () public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException { try { SyndFeed feed = getFeed (req); String feedType = req.getParameter (FEED_TYPE); feedType = (feedType != null) ? feedType : _defaultFeedType; feed.setFeedType (feedType); res.setContentType (MIME_TYPE); SyndFeedOutput output = new SyndFeedOutput (); output.output (feed, res.getWriter ()); } catch (FeedException ex) { String msg = COULD_NOT_GENERATE_FEED_ERROR; log (msg, ex); res.sendError (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); } } // doGet () protected SyndFeed getFeed (HttpServletRequest req) throws IOException,FeedException { SyndFeed feed = new SyndFeedImpl (); feed.setTitle ("Exemple de flux (crée avec ROME)"); feed.setLink ("http://www.mkhelif.fr/"); feed.setDescription ("Ce flux a été crée grâce à la librairie ROME"); List entries = new ArrayList (); SyndEntry entry; SyndContent description; entry = new SyndEntryImpl (); entry.setTitle ("ROME v0.1"); entry.setLink ("http://wiki.java.net/bin/view/Javawsxml/rome01"); try { entry.setPublishedDate (DATE_PARSER.parse ("2004-06-08")); } catch (ParseException ex) { // Impossible dans cet exemple } description = new SyndContentImpl (); description.setType ("text/plain"); description.setValue ("Initial release of ROME"); entry.setDescription (description); entries.add (entry); entry = new SyndEntryImpl (); entry.setTitle ("Rome v0.2"); entry.setLink ("http://wiki.java.net/bin/view/Javawsxml/rome02"); try { entry.setPublishedDate (DATE_PARSER.parse("2004-06-16")); } catch (ParseException ex) { // Impossible dans cet exemple } description = new SyndContentImpl (); description.setType ("text/plain"); description.setValue ("Bug fixes, minor API changes and some new features"+ "For details check the <a href="http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#Rome">Changes Log for 0.2</a>"); entry.setDescription (description); entries.add (entry); entry = new SyndEntryImpl (); entry.setTitle ("ROME v0.3"); entry.setLink ("http://wiki.java.net/bin/view/Javawsxml/rome03"); try { entry.setPublishedDate (DATE_PARSER.parse("2004-07-27")); } catch (ParseException ex) { // Impossible dans cet exemple } description = new SyndContentImpl (); description.setType ("text/html"); description.setValue ("Bug fixes, API changes, some new features and some Unit testing" + "For details check the <a href="http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#Rome">Changes Log for 0.3</a>"); entry.setDescription (description); entries.add (entry); entry = new SyndEntryImpl (); entry.setTitle ("ROME v0.4"); entry.setLink ("http://wiki.java.net/bin/view/Javawsxml/rome04"); try { entry.setPublishedDate (DATE_PARSER.parse("2004-09-24")); } catch (ParseException ex) { // Impossible dans cet exemple } description = new SyndContentImpl (); description.setType ("text/html"); description.setValue ("Bug fixes, API changes, some new features, Unit testing completed" + "For details check the <a href="http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#Rome">Changes Log for 0.4</a>"); entry.setDescription (description); entries.add (entry); feed.setEntries (entries); return feed; } // getFeed () } // FeedServlet |
Pour utiliser cette Servlet nous devons créer une application Web pour laquelle il nous faut un fichier web.xml :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <code> < ?xml version="1.0" encoding="UTF-8"?> < !DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web> <display>Exemple ROME</display> <servlet> </servlet><servlet -name>FeedServlet</servlet> <servlet -class>com.mkhelif.rome.exemples.FeedServlet</servlet> <init -param> <param -name>default.feed.type</param> <param -value>rss_2.0</param> </init> <servlet -mapping> </servlet><servlet -name>FeedServlet</servlet> <url -pattern>/feed</url> </web> </code> |
Pour créer l’application lancer la commande suivante dans le sous-projet d’exemples : maven war.
Le fichier WAR, exemples-rome.war, va être crée dans le répertoire cible. Déployer le WAR dans un conteneur de Servlet et la FeedServlet devrait être prête.
Si vous utilisé Tomcat 4 ou Tomcat 5 et que le fichier WAR a été mis dans le répertoire ${TOMCAT}/webapps, l’URL pour accéder à la Servlet devrais être http://localhost:8080/exemples-rome/feed.
20 mars 2008 - 12:37
Bonjour,
quelle est la différence entre SyndEntry et SyndEntryImpl?
20 mars 2008 - 15:11
Salut,
Je te conseil de lire la documentation de ROME : https://rome.dev.java.net/apidocs/0_9/overview-summary.html.
Sinon la différence est que SyndEntry est une interface et SyndEntryImpl est l’implémentation de cette interface.
a+
14 août 2009 - 10:29
Le code que tu proposes est très excellent !!
Mais, à mon avis le flux RSS généré n’est pas dynamique.
Par exemple quand je lit :
« »" »" »" »"
description = new SyndContentImpl ();
description.setType ( »text/html »);
description.setValue ( »Bug fixes, API changes, some new features, Unit testing completed » +
« For details check the Changes Log for 0.4« );
entry.setDescription (description);
entries.add (entry);
« »" »" »" »" »"
Je constate que le titre » Bug fixes, API changes, some new features, Unit testing completed »
restera toujours » Bug fixes, API changes, some new features, Unit testing completed »
Alors je me demande est-ce que tu le fais volontairement ? Sinon, quelles solutions
tu proposes pour que les titres des infos dans ton flux RSS soientt aussi dynamiques comme les infos elles-meme ?
Merci !
15 août 2009 - 07:54
Salut,
En effet dans cet exemple le flux RSS sera toujours le même. Pour le rendre dynamique il suffit de changer les données par des variables venant de ton application web.
Par exemple si tu as développé un blog et que tu souhaites fournir un flux RSS à tes lecteurs :
public SyndFeed getFeed (List articles) { List entries = new ArrayList (); SyndEntry entry; SyndContent description; for (int i = 0 ; i < articles.size () ; i++) { Article article = (Article) articles.get (i); entry = new SyndEntryImpl (); entry.setTitle (article.getTitle ()); entry.setLink (article.getLink ()); entry.setPublishedDate (article.getDate ()); description = new SyndContentImpl (); description.setType ("text/plain"); description.setValue (article.getContent ()); entry.setDescription (description); entries.add (entry); } feed.setEntries (entries); return feed; }Voilà c'est juste un exemple, mais j'espère que tu auras compris le principe.
a+