<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.netapsys.fr/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Netapsys Blog</title>
  <link>http://blog.netapsys.fr/index.php/</link>
  <atom:link href="http://blog.netapsys.fr/index.php/feed/author/benoit_cotinat/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Wed, 08 Feb 2012 20:39:38 +0100</pubDate>
  <copyright>Netapsys 2008 - 2011</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>[Eclipse] Recherche camelCase</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/06/07/%5BEclipse%5D-Recherche-camelCase</link>
    <guid isPermaLink="false">urn:md5:e1ab8ecbe688fff1d78aff5987b707f9</guid>
    <pubDate>Tue, 07 Jun 2011 19:34:00 +0200</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>camelCase</category><category>Eclipse</category>    
    <description>&lt;p&gt;Notre IDE préféré possède en effet cette petite &lt;em&gt;feature&lt;/em&gt;, ma foi fort sympathique, pour la recherche de fichier.&lt;/p&gt;    &lt;p&gt;Lors de la recherche de ressources (Ctrl+Shift+R) ou de types (Ctrl+Shift+T), il est en effet possible de mettre uniquement les lettres en majuscule.
Par exemple pour un fichier nommé &lt;strong&gt;MonFichierDeTest.java&lt;/strong&gt;, il vous suffira de rechercher &lt;strong&gt;MFDT&lt;/strong&gt;... voir même souvent moins, les deux ou trois premières lettres suffisant généralement.&lt;/p&gt;


&lt;p&gt;Démonstration en image&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/Eclipse_camelCase_OpenType.png&quot; alt=&quot;Eclipse_camelCase_OpenType.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/p&gt;


&lt;p&gt;À noter que j'aurais très bien pu obtenir le même résultat en recherchant &lt;strong&gt;GenericDH&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Très utile lorsque vous avez plusieurs fichiers/classes qui commencent par les mêmes 3-4 premiers mots&amp;nbsp;!&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/06/07/%5BEclipse%5D-Recherche-camelCase#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/06/07/%5BEclipse%5D-Recherche-camelCase#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/266</wfw:commentRss>
      </item>
    
  <item>
    <title>[JMeter] Création et exécution de jeu de test</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/05/12/%5BJMeter%5D-Cr%C3%A9ation-et-ex%C3%A9cution-de-jeu-de-test</link>
    <guid isPermaLink="false">urn:md5:759c7200ffbdafd266106c7cb8efc1a7</guid>
    <pubDate>Thu, 12 May 2011 21:13:00 +0200</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
            
    <description>&lt;p&gt;&lt;a href=&quot;http://jakarta.apache.org/jmeter/&quot; hreflang=&quot;fr&quot;&gt;JMeter&lt;/a&gt; est un outil open-source permettant de faire des tests fonctionnels, ainsi que des tests de montée en charge d'applications web.&lt;/p&gt;


&lt;p&gt;Sa configuration n'étant pas très intuitive, nous allons voir dans ce billet comment :&lt;br /&gt;
1- Enregistrer un jeu de test ;&lt;br /&gt;
2- Placer des assertions ;&lt;br /&gt;
3- Jouer le jeu de test.&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Vous trouverez à la fin de ce billet le plan de test d'exemple qui a servi à sa rédaction.&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;1- Enregistrer un jeu de test&lt;/h2&gt;


&lt;p&gt;Pour enregistrer simplement les différentes actions faites sur l'application, JMeter contient un &lt;ins&gt;proxy HTTP&lt;/ins&gt;. Ce proxy va sauvegarder les requêtes qu'il verra passer, ce qui permettra de les réutiliser dans le jeu de test.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Configuration du navigateur&lt;/h3&gt;


&lt;p&gt;Il faut d'abord dire à votre navigateur d'utiliser le proxy de JMeter, à l'adresse &lt;strong&gt;localhost&lt;/strong&gt;, et sur un port libre (ici &lt;strong&gt;9999&lt;/strong&gt;).&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Configuration de JMeter&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faire un &lt;strong&gt;clic-droit sur &quot;Plan de test&quot; &amp;gt; Ajouter &amp;gt; Groupe d'unités&lt;/strong&gt;. Ce groupe d'unités (ou groupe de threads), va stocker les requêtes qui seront enregistrées par le proxy. Nous reviendrons sur sa configuration lors des tests de montée en charge.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Faire un &lt;strong&gt;clic-droit sur &quot;Plan de travail&quot; &amp;gt; Ajouter &amp;gt; Eléments hors test &amp;gt; Serveur proxy HTTP&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Configuration_proxy_http.png&quot; title=&quot;JMeter-Configuration_proxy_http.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Configuration_proxy_http.png&quot; alt=&quot;JMeter-Configuration_proxy_http.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Les différents points de configuration sur cet écran sont :&lt;br /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Le port qui est utilisé pour enregistrer les requêtes ;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Le contrôleur cible, qui va contenir les requêtes enregistrées ;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Les motifs d'URL à inclure et à exclure (attention à la syntaxe&amp;nbsp;: &lt;strong&gt;.*\.extension&lt;/strong&gt;).&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il ne reste plus qu'à lancer le serveur.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Enregistrement&lt;/h3&gt;


&lt;p&gt;Pour cet exemple, nous allons naviguer sur l'interface de management d'un tomcat lancé en local, et déployer une nouvelle application (ce qui va permettre de tester l'upload de fichier).&lt;br /&gt;
Au fur et à mesure de la navigation, les requêtes se rajoutent au &lt;ins&gt;groupe d'unités&lt;/ins&gt; spécifié dans le proxy. Par défaut elles sont nommées par le chemin de la page, mais il est conseillé de les renommer pour avoir des résultats plus parlant lors de l'exécution du jeu de test.&lt;/p&gt;


&lt;p&gt;Lors du déploiement d'une nouvelle application (et donc de l'upload d'un fichier), on peut voir que JMeter a bien sauvegardé le fichier utilisé dans la requête&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Deploiement.png&quot; title=&quot;JMeter-Deploiement.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Deploiement.png&quot; alt=&quot;JMeter-Deploiement.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;Attention&lt;/ins&gt;&amp;nbsp;: il faut que le fichier en question soit dans le répertoire &lt;strong&gt;/bin&lt;/strong&gt; de jmeter.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;2- Placer des assertions&lt;/h2&gt;


&lt;p&gt;Les assertions servent à vérifier que la navigation se passe correctement, et que la page demandée s'affiche correctement lors de l'exécution automatique du jeu de test. Différents type d'assertions sont disponibles, nous allons ici faire de vérifications &quot;de base&quot; sur le contenu de la réponse.&lt;br /&gt;
Pour ajouter une assertion, faire un &lt;strong&gt;clic-droit sur la requête &amp;gt; Ajouter &amp;gt; Assertions &amp;gt; Assertion Réponse&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Assertion.png&quot; title=&quot;JMeter-Assertion.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Assertion.png&quot; alt=&quot;JMeter-Assertion.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;3- Jouer le jeu de test&lt;/h2&gt;


&lt;p&gt;Une fois le scénario enregistré, nous pouvons couper le proxy, et fermer le navigateur. Quelques étapes de configuration sont encore nécessaires afin de pouvoir exécuter notre jeu de test, et monitorer notre serveur.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Configuration HTTP&lt;/h3&gt;


&lt;p&gt;Pour permettre à JMeter de se connecter à l'administration de tomcat, il faut rajouter un composant d'authentification spécifique, en faisant un &lt;strong&gt;clic-droit sur &quot;Groupe d'unités&quot; &amp;gt; Ajouter &amp;gt; Configuration &amp;gt; &quot;Gestionnaire d'autorisation HTTP&quot;&lt;/strong&gt;.&lt;br /&gt;
Il faut paramétrer ce composant en indiquant l'identifiant et le mot de passe de connexion à l'administration du serveur.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Gestionnaire_autorisations_http.png&quot; title=&quot;JMeter-Gestionnaire_autorisations_http.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Gestionnaire_autorisations_http.png&quot; alt=&quot;JMeter-Gestionnaire_autorisations_http.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Pour pouvoir suivre la santé du serveur, il faut ajouter une &lt;ins&gt;requête HTTP&lt;/ins&gt; (&lt;strong&gt;clic-droit sur &quot;Groupe d'unités&quot; &amp;gt; Ajouter &amp;gt; Echantillons &amp;gt; Requête HTTP&lt;/strong&gt;) vers la page de monitoring de tomcat &lt;strong&gt;/manager/status&lt;/strong&gt;, en ajoutant le paramètre &lt;strong&gt;XML&lt;/strong&gt; avec la valeur &lt;strong&gt;true&lt;/strong&gt;, et indiquer qu'il faut utiliser cette requête en tant que moniteur.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Server_status.png&quot; title=&quot;JMeter-Server_status.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Server_status.png&quot; alt=&quot;JMeter-Server_status.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Il faut indiquer à JMeter les paramètres par défaut (adresse IP, port, chemin de l'application) à utiliser pour exécuter les requêtes qu'il a enregistré. Pour cela, il faut faire un &lt;strong&gt;clic-droit sur &quot;Groupe d'unités&quot; &amp;gt; Ajouter &amp;gt; Configurations &amp;gt; Paramètres HTTP par défaut&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Parametres_HTTP.png&quot; title=&quot;JMeter-Parametres_HTTP.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Parametres_HTTP.png&quot; alt=&quot;JMeter-Parametres_HTTP.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Ce composant permet de dissocier l'enregistrement du scénario, et son exécution sur des serveurs différents.&lt;br /&gt;
&lt;ins&gt;Attention&lt;/ins&gt;&amp;nbsp;: pour exécuter le scénario en local, il faut bien mettre &lt;strong&gt;127.0.0.1&lt;/strong&gt; en nom/adresse, et non pas &lt;strong&gt;localhost&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Monitoring&lt;/h3&gt;


&lt;p&gt;Le &lt;ins&gt;groupe d'unités&lt;/ins&gt; permet de paramétrer l'exécution même du jeu de test. Son paramétrage est assez poussé en laissant la main sur le nombre d'utilisateurs, le nombre d'itérations du plan de test, la durée de montée en charge, la possibilité de programmer le démarrage des test, ...&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Groupe_d__unites.png&quot; title=&quot;JMeter-Groupe_d__unites.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Groupe_d__unites.png&quot; alt=&quot;JMeter-Groupe_d__unites.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Différents &quot;récepteurs&quot; (=listeners, &lt;strong&gt;clic-droit sur &quot;Groupe d'unités&quot; &amp;gt; Ajouter &amp;gt; Récepteurs &amp;gt; ...&lt;/strong&gt;) existent, selon ce que l'on veut monitorer&amp;nbsp;: charge/mémoire du serveur, temps d'exécution des requêtes, ...
Je vais montrer ceux que je trouve le plus parlant.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Le &lt;ins&gt;moniteur de résultats&lt;/ins&gt; s'appuie sur la requête HTTP que l'on a paramétrée à l'étape précédente. Il permet d'avoir une vue de la santé globale du serveur, ainsi que des informations plus détaillées sur la mémoire et le nombre d'exécuteurs tomcat disponibles&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Moniteur_Sante.png&quot; title=&quot;JMeter-Moniteur_Sante.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Moniteur_Sante.png&quot; alt=&quot;JMeter-Moniteur_Sante.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Moniteur_Perf.png&quot; title=&quot;JMeter-Moniteur_Perf.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Moniteur_Perf.png&quot; alt=&quot;JMeter-Moniteur_Perf.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
L'&lt;ins&gt;arbre de résultats&lt;/ins&gt; permet de vérifier que les différentes assertions que l'on a pu placer sont bien vérifiées, avec les informations de la requête et de la réponse.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Arbre_resultats.png&quot; title=&quot;JMeter-Arbre_resultats.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Arbre_resultats.png&quot; alt=&quot;JMeter-Arbre_resultats.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Enfin, le &lt;ins&gt;rapport agrégé&lt;/ins&gt; permet d'avoir les statistiques de temps d'exécution de chaque requête.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Rapport_agrege.png&quot; title=&quot;JMeter-Rapport_agrege.png&quot;&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/JMeter/JMeter-Rapport_agrege.png&quot; alt=&quot;JMeter-Rapport_agrege.png&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
À noter que chaque récepteur permet d'enregistrer les résultats des tests dans un fichier csv, ce qui permet de l'utiliser après dans votre tableur favori pour exploiter différemment les données.&lt;/p&gt;


&lt;p&gt;Bons tests&amp;nbsp;!&lt;/p&gt;</description>
    
          <enclosure url="http://blog.netapsys.fr/public/JMeter/blog.jmx"
      length="38996" type="text/plain" />
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/05/12/%5BJMeter%5D-Cr%C3%A9ation-et-ex%C3%A9cution-de-jeu-de-test#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/05/12/%5BJMeter%5D-Cr%C3%A9ation-et-ex%C3%A9cution-de-jeu-de-test#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/262</wfw:commentRss>
      </item>
    
  <item>
    <title>Sérialisation/Désérialisation XML avec Camel</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/03/16/S%C3%A9rialisation/D%C3%A9s%C3%A9rialisation-XML-avec-Camel</link>
    <guid isPermaLink="false">urn:md5:43ee168979f7ac62449c5ab3b7b2773b</guid>
    <pubDate>Tue, 22 Mar 2011 17:20:00 +0100</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>camel</category><category>JAXB</category><category>xml</category><category>xsd</category><category>xstream</category>    
    <description>&lt;p&gt;Je vais présenter ici quelques moyens pour faire de la sérialisation/désérialisation en XML avec Camel, selon différents besoins&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mapping &quot;simple&quot; de et/ou vers des pojos java existants&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;mapping à partir d'un fichier XSD fourni, ou mapping à partir d'un modèle Java bindé.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les sources (mavenisées) des exemples sont fournies à la fin de ce billet.&lt;/p&gt;    &lt;p&gt;Tout d'abord, partons d'une configuration de base :&lt;br /&gt;
&lt;br /&gt;
&lt;ins&gt;Nos pojos existants&lt;/ins&gt;&amp;nbsp;:
&lt;br /&gt;
&lt;strong&gt;EssaiClinique.java&lt;/strong&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Description d'un essai.
 * @author NETAPSYS
 * @date 15 mars 2011
 * @version $Revision$ $Date$
 */
public class EssaiClinique implements Serializable {
    /** Serial ID. */
    private static final long serialVersionUID = -3188027620920487407L;

    /** Nom de l'essai. */
    private String nom;

    /** Nombre de patients pour l'essai. */
    private Integer nbPatient;

    /** Date de début de l'essai. */
    private Date dateDebut;

    /** Liste des médicaments nécessaires à l'essai. */
    private List&amp;lt;Medicament&amp;gt; medicaments;

    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer();
        sb.append(&amp;quot;
EssaiClinique &amp;quot; + this.nom + &amp;quot; du &amp;quot; + this.dateDebut);
        for (final Medicament medicament : this.medicaments) {
            sb.append(medicament);
        }
        return sb.toString();
    }

    // Getters &amp;amp; Setters
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;Medicament.java&lt;/strong&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Description d'un médicament.
 * @author NETAPSYS
 * @date 15 mars 2011
 * @version $Revision$ $Date$
 */
public class Medicament implements Serializable {
    /** Serial ID. */
    private static final long serialVersionUID = 3111655483593665106L;

    /** Nom du médicament. */
    private String nom;

    /** Concentration du médicament. */
    private BigDecimal concentration;

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return &amp;quot;
Medicament &amp;quot; + this.nom + &amp;quot; à concentration de &amp;quot; + this.concentration;
    }

    // Getters &amp;amp; Setters
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;ins&gt;Contexte camel&lt;/ins&gt; :&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot; 
    xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
	xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd&amp;quot;&amp;gt;

	&amp;lt;camelContext trace=&amp;quot;false&amp;quot; xmlns=&amp;quot;http://camel.apache.org/schema/spring&amp;quot;&amp;gt;
		&amp;lt;packageScan&amp;gt;
			&amp;lt;package&amp;gt;com.netapsys.routes&amp;lt;/package&amp;gt;
		&amp;lt;/packageScan&amp;gt;
	&amp;lt;/camelContext&amp;gt;
&amp;lt;/beans&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;ins&gt;Classe de test permettant d'appeller les routes&lt;/ins&gt; :&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;
public class RoutesTest extends CamelSpringTestSupport {
    /** {@inheritDoc} */
    @Override
    public void setUp() throws Exception {
        super.setUp();
    }

    /** {@inheritDoc} */
    @Override
    protected AbstractXmlApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext(&amp;quot;/config/camel-context.xml&amp;quot;);
    }
}
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;h2&gt;Mapping Pojo/XML&lt;/h2&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/camel-marshalling-xml/Serialisation-Deserialisation_XML_avec_Camel-xstream.png&quot; alt=&quot;Camel-xstream&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/p&gt;


&lt;h3&gt;Mise en place&lt;/h3&gt;


&lt;h4&gt;Librairie&lt;/h4&gt;

&lt;p&gt;Si le besoin est uniquement de faire de l'export/import xml de pojos Java existant (pour faire de la sauvegarde, ou partager des données pour une application répartie par exemple), le plus simple est d'utiliser le serialiseur Xstream.&lt;br /&gt;
Pour cela il faut commencer par inclure camel-xstream au classpath. Avec Maven il faut rajouter la dépendance&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.camel&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;camel-xstream&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4&gt;Camel&lt;/h4&gt;

&lt;p&gt;Dans la définition de notre contexte camel, il faut rajouter le format qui sera utilisé dans la route&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;dataFormats&amp;gt;
    &amp;lt;xstream id=&amp;quot;xstream-utf8&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;/&amp;gt;
&amp;lt;/dataFormats&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
La route permettant la sérialisation/désérialisation&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Routes utilisant le marshaller xstream.
 * @author NETAPSYS
 * @date 16 mars 2011
 * @version $Revision$ $Date$
 */
public class XStreamRoutes extends RouteBuilder {
    /** @see org.apache.camel.builder.RouteBuilder#configure() */
    @Override
    public void configure() throws Exception {
        this.from(&amp;quot;direct:xstream-marshal&amp;quot;)
            .marshal(&amp;quot;xstream-utf8&amp;quot;)
            .to(&amp;quot;file:/testCamel?fileName=essais-xstream.xml&amp;quot;);

        this.from(&amp;quot;direct:xstream-unmarshal&amp;quot;)
	    .unmarshal(&amp;quot;xstream-utf8&amp;quot;)
            .to(&amp;quot;log:com.netapsys.routes?level=DEBUG&amp;quot;);
    }
}
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4&gt;Test&lt;/h4&gt;

&lt;p&gt;Et enfin le test de nos routes&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Appelle les routes pour la sérialisation/désérialisation.
 * @throws Exception Exception lors de l'exécution des routes.
 */
@Test
public void test() throws Exception {
    final EssaiClinique essai = this.getEssaiForTest();

    this.template.sendBody(&amp;quot;direct:xstream-marshal&amp;quot;, essai);

    Thread.sleep(2000);

    this.template.sendBody(&amp;quot;direct:xstream-unmarshal&amp;quot;, new File(&amp;quot;/testCamel/essais-xstream.xml&amp;quot;));

    Thread.sleep(2000);
}

/** Créé un Essai pour le test.
 * @return Essai
 */
private EssaiClinique getEssaiForTest() {
    // Créé un essai de test avec 2 médicaments.
    // Pour bien gérer l'export des concentrations, ne pas oublier de paramétrer le MathContext :
    final Medicament m1 = new Medicament();
    m1.setConcentration(new BigDecimal(1.2345, MathContext.DECIMAL32));
}
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Résultats&lt;/h3&gt;

&lt;h4&gt;Sérialisation&lt;/h4&gt;

&lt;p&gt;En éditant le fichier XML créé (&lt;strong&gt;/testCamel/essais-xstream.xml&lt;/strong&gt;), on peut voir qu'il correspond bien à nos attentes&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
&amp;lt;com.netapsys.model.EssaiClinique&amp;gt;
    &amp;lt;nom&amp;gt;Essai n°1&amp;lt;/nom&amp;gt;
    &amp;lt;nbPatient&amp;gt;3&amp;lt;/nbPatient&amp;gt;
    &amp;lt;dateDebut&amp;gt;2011-03-16 18:10:08.270 CET&amp;lt;/dateDebut&amp;gt;
    &amp;lt;medicaments&amp;gt;
        &amp;lt;com.netapsys.model.Medicament&amp;gt;
            &amp;lt;nom&amp;gt;Médicament 1&amp;lt;/nom&amp;gt;
            &amp;lt;concentration&amp;gt;1.234500&amp;lt;/concentration&amp;gt;
        &amp;lt;/com.netapsys.model.Medicament&amp;gt;
        &amp;lt;com.netapsys.model.Medicament&amp;gt;
            &amp;lt;nom&amp;gt;Médicament 2&amp;lt;/nom&amp;gt;
            &amp;lt;concentration&amp;gt;2.000100&amp;lt;/concentration&amp;gt;
        &amp;lt;/com.netapsys.model.Medicament&amp;gt;
    &amp;lt;/medicaments&amp;gt;
&amp;lt;/com.netapsys.model.EssaiClinique&amp;gt;
&lt;/pre&gt;

&lt;p&gt;On peut voir que par défaut XStream nomme les noeuds avec le nom complet des classes, ce qui lui permet de s'y retrouver lors de la désérialisation.
&lt;br /&gt;&lt;/p&gt;

&lt;h4&gt;Désérialisation&lt;/h4&gt;

&lt;p&gt;En regardant les logs, on peut voir que les informations on bien été récupérées&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
2011/03/16 18:29:19 DEBUG service.process(74) : Exchange[ExchangePattern:InOnly, BodyType:com.netapsys.model.EssaiClinique, Body:
EssaiClinique Essai n°1 du Wed Mar 16 18:29:16 CET 2011
Medicament Médicament 1 à concentration de 1.234500
Medicament Médicament 2 à concentration de 2.000100]
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;h2&gt;Mapping à partir d'un fichier XSD / Modèle Java bindé&lt;/h2&gt;


&lt;p&gt;Il peut être nécessaire de faire évoluer une application pour exporter des données en XML, tout en respectant un fichier XSD fourni.&lt;br /&gt;
Dans ce cas le sérialiseur JAXB va être utilisé, et il faudra préalablement passer par une conversion en java entre nos pojos de notre modèle métier et le modèle qui sera généré. Tout d'abord, il va falloir commencer par générer le modèle Java correspondant au XSD.&lt;/p&gt;


&lt;p&gt;Ce type de sérialisation/désérialisation peut aussi être utilisé si nos pojos sont déjà bindés.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/camel-marshalling-xml/Serialisation-Deserialisation_XML_avec_Camel-jaxb.png&quot; alt=&quot;Camel-jaxb&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/p&gt;


&lt;h3&gt;1-Génération du modèle&lt;/h3&gt;


&lt;h4&gt;XJC&lt;/h4&gt;


&lt;p&gt;&lt;a href=&quot;http://download.oracle.com/javase/6/docs/technotes/tools/share/xjc.html&quot; hreflang=&quot;fr&quot;&gt;XJC&lt;/a&gt; est un outil inclus dans le JDK qui va nous permettre de générer le modèle Java à partir d'un fichier XSD.
Le fichier XSD de référence, &lt;strong&gt;essais.xsd&lt;/strong&gt;, est dans le projet &lt;strong&gt;camel-jaxb&lt;/strong&gt;, lié à ce billet.&lt;br /&gt;
XJC a besoin d'un fichier de binding, qui contient principalement le chemin vers le fichier XSD, et le package où seront stockées les classes créées.&lt;br /&gt;
&lt;br /&gt;
&lt;ins&gt;binding.xjb&lt;/ins&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;bindings schemaLocation=&amp;quot;../essais.xsd&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot; version=&amp;quot;2.1&amp;quot;&amp;gt;
    &amp;lt;schemaBindings&amp;gt;
        &amp;lt;package name=&amp;quot;com.netapsys.model.xml&amp;quot; /&amp;gt;
    &amp;lt;/schemaBindings&amp;gt;
    &amp;lt;globalBindings&amp;gt;
        &amp;lt;serializable uid=&amp;quot;100&amp;quot; /&amp;gt;
    &amp;lt;/globalBindings&amp;gt;
&amp;lt;/bindings&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
Commande à exécuter :&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;
&amp;quot;C:\Program Files\Java\jdk1.6.0_20\bin\xjc.exe&amp;quot; -d D:\Projet\camel-jaxb\src\main\java\ -extension D:\Projet\camel-jaxb\src\mainesources\essais.xsd -b D:\Projet\camel-xsd\src\mainesources\schema\binding.xjb
&lt;/pre&gt;

&lt;p&gt;Explication succincte des paramètres&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-d&lt;/strong&gt;&amp;nbsp;: répertoire où se situe le package spécifié dans le fichier &lt;strong&gt;xjb&lt;/strong&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-extension&lt;/strong&gt;&amp;nbsp;: chemin vers le fichier &lt;strong&gt;xsd&lt;/strong&gt; (attention, le fait de mettre un chemin relatif peut être source de bug lors de l'exécution de la commande)&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-b&lt;/strong&gt;&amp;nbsp;: emplacement du fichier &lt;strong&gt;xjb&lt;/strong&gt; (même remarque que ci-dessus).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Modèle&lt;/h4&gt;


&lt;p&gt;Les traces dans les logs montrent les classes créées, qui sont visibles, dans le package spécifié dans le fichier de binding. Pour plus d'informations sur les annotations utilisées, je vous invite à consulter &lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2010/12/02/RESTer-simple-avec-Spring-et-Jaxb-Partie-1-%3A-Binding-avec-JAXB&quot;&gt;ce post&lt;/a&gt;.&lt;br /&gt;
Pour notre exemple, ces classes générées correspondront à un modèle métier déjà bindé.&lt;/p&gt;


&lt;h3&gt;2-Mise en place&lt;/h3&gt;


&lt;h4&gt;Librairie&lt;/h4&gt;


&lt;p&gt;Pour effectuer la sérialisation/désérialisation, il faut inclure la librairie &lt;strong&gt;camel-jaxb&lt;/strong&gt; au classpath. Avec maven, il faut rajouter la dépendance&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.camel&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;camel-jaxb&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;h4&gt;Camel&lt;/h4&gt;


&lt;p&gt;Il n'y a pas de modification à apporter au contexte Camel.&lt;br /&gt;
Écrivons la route que nous appellerons pour effectuer la sérialisation/désérialisation&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** @see org.apache.camel.builder.RouteBuilder#configure() */
@Override
public void configure() throws Exception {
    final DataFormat dataFormat = new JaxbDataFormat(&amp;quot;com.netapsys.model.xml&amp;quot;);

    this.from(&amp;quot;direct:jaxb-marshal&amp;quot;)
          .marshal(dataFormat)
          .to(&amp;quot;file:/testCamel?fileName=essais-jaxb.xml&amp;quot;);

    this.from(&amp;quot;direct:jaxb-unmarshal&amp;quot;).unmarshal(dataFormat).to(&amp;quot;log:logger.service?level=DEBUG&amp;quot;);
}
&lt;/pre&gt;

&lt;p&gt;Cette route ressemble beaucoup à la première, à la différence de l'utilisation d'une implémentation de &lt;strong&gt;DataFormat&lt;/strong&gt; spécifique à JAXB, qui connaît l'emplacement du modèle à utiliser.&lt;/p&gt;


&lt;h4&gt;Test&lt;/h4&gt;


&lt;p&gt;Là aussi le test ressemble beaucoup au précédent&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Test de sérialisation/désérialisation.
 * @throws Exception Exception lors de l'exécution des routes.
 */
@Test
public void test() throws Exception {
    final XMLEssaiClinique essai1 = this.getEssaiForTest();

    this.template.sendBody(&amp;quot;direct:jaxb-marshal&amp;quot;, essai1);

    Thread.sleep(2000);

    this.template.sendBody(&amp;quot;direct:jaxb-unmarshal&amp;quot;, new File(&amp;quot;/testCamel/essais-jaxb.xml&amp;quot;));

    Thread.sleep(2000);
}

/** Créé un Essai pour le test.
 * @return Bean du modèle XML pour le test.
 * @throws DatatypeConfigurationException Erreur lors de la conversion des données.
 */
private XMLEssaiClinique getEssaiForTest() throws DatatypeConfigurationException {
    // Attention à la gestion de la date :
    final XMLEssaiClinique essai1 = new XMLEssaiClinique();
    essai1.setDateDebut(DatatypeFactory.newInstance()
                                          .newXMLGregorianCalendar(new GregorianCalendar()));
    // Valorisation de l'essai avec deux médicaments.
}
&lt;/pre&gt;

&lt;p&gt;La principale différence ici est le type des objets passés à la route. Il faut en effet passer des objets que JAXB connaît. Dans une application existante, cela implique la mise en place d'un mapping java entre les pojos existants (&lt;strong&gt;EssaiClinique.java&lt;/strong&gt; et &lt;strong&gt;Medicament.java&lt;/strong&gt; dans notre cas), vers les pojos du modèle XML générés par &lt;strong&gt;XJC&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;3-Résultats&lt;/h3&gt;


&lt;h4&gt;Sérialisation&lt;/h4&gt;


&lt;p&gt;Ici encore, le fichier XML correspond à nos attentes&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;
&amp;lt;XMLEssaiClinique&amp;gt;
    &amp;lt;nom&amp;gt;Essai n°1&amp;lt;/nom&amp;gt;
    &amp;lt;nbPatient&amp;gt;3&amp;lt;/nbPatient&amp;gt;
    &amp;lt;dateDebut&amp;gt;2011-03-17+01:00&amp;lt;/dateDebut&amp;gt;
    &amp;lt;medicaments&amp;gt;
        &amp;lt;XMLMedicament&amp;gt;
            &amp;lt;nom&amp;gt;Médicament 1&amp;lt;/nom&amp;gt;
            &amp;lt;concentration&amp;gt;1.234500&amp;lt;/concentration&amp;gt;
        &amp;lt;/XMLMedicament&amp;gt;
        &amp;lt;XMLMedicament&amp;gt;
            &amp;lt;nom&amp;gt;Médicament 2&amp;lt;/nom&amp;gt;
            &amp;lt;concentration&amp;gt;2.000100&amp;lt;/concentration&amp;gt;
        &amp;lt;/XMLMedicament&amp;gt;
    &amp;lt;/medicaments&amp;gt;
&amp;lt;/XMLEssaiClinique&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4&gt;Désérialisation&lt;/h4&gt;

&lt;p&gt;Toujours en étudiant les logs, on peut voir que les objets ont bien été créés. Pour les besoins du test, j'ai surchargé la méthode &lt;strong&gt;toString()&lt;/strong&gt; dans les classes du modèle XML générées par &lt;strong&gt;xjc&lt;/strong&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
XMLEssaiClinique Essai n°1 du 2011-03-17+01:00
XMLMedicament Médicament 1 à concentration de 1.234500
XMLMedicament Médicament 2 à concentration de 2.000100
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Nous avons présenté deux méthodes pour faire de la sérialisation/désérialisation d'objets en XML, chacune des méthodes répondant à un besoin différent. Les deux premiers avantages que je vois à l'utilisation de Camel sont la simplicité de la mise en place du système, tout en gardant de nombreuses possibilités de personnalisation grâce aux différentes annotations disponibles.
&lt;br /&gt;
&lt;br /&gt;
&lt;ins&gt;Liens&lt;/ins&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XJC&amp;nbsp;: &lt;a href=&quot;http://download.oracle.com/javase/6/docs/technotes/tools/share/xjc.html&quot; hreflang=&quot;fr&quot;&gt;http://download.oracle.com/javase/6/docs/technotes/tools/share/xjc.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Camel - XStream&amp;nbsp;: &lt;a href=&quot;http://camel.apache.org/xstream.html&quot; hreflang=&quot;fr&quot;&gt;http://camel.apache.org/xstream.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Camel - JAXB&amp;nbsp;: &lt;a href=&quot;http://camel.apache.org/jaxb.html&quot; hreflang=&quot;fr&quot;&gt;http://camel.apache.org/jaxb.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
          <enclosure url="http://blog.netapsys.fr/public/camel-marshalling-xml/camel-xstream.tar"
      length="20480" type="application/x-tar" />
          <enclosure url="http://blog.netapsys.fr/public/camel-marshalling-xml/camel-jaxb.tar"
      length="40960" type="application/x-tar" />
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/03/16/S%C3%A9rialisation/D%C3%A9s%C3%A9rialisation-XML-avec-Camel#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/03/16/S%C3%A9rialisation/D%C3%A9s%C3%A9rialisation-XML-avec-Camel#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/235</wfw:commentRss>
      </item>
    
  <item>
    <title>Comment scanner des répertoires ?</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/02/11/Comment-scanner-des-r%C3%A9pertoires</link>
    <guid isPermaLink="false">urn:md5:de660a81c8b435ca968f77c45a38b0ab</guid>
    <pubDate>Sun, 20 Feb 2011 18:10:00 +0100</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>camel</category>    
    <description>    &lt;p&gt;Le besoin de scanner le contenu de répetoires est assez courant, pour analyser des données, nettoyer des répertoires, ... à intervalles réguliers.&lt;/p&gt;


&lt;p&gt;Une des réponses à ce problème est de mettre en place des CRON, appelant des classes java. C'est une solution, mais elle n'enlève pas le côté complexe de gestion des fichiers en java, surtout si ceux-ci sont situés sur un répertoire distant.&lt;/p&gt;


&lt;p&gt;Or nous aimons les choses simples et bien faites :). Pour cela, la solution que nous avons choisie est d'utiliser Camel.&lt;/p&gt;


&lt;p&gt;Cet outil, à la configuration très complète (mais pas complexe !) nous permet de &quot;consommer&quot; (traiter, transférer, ...) des fichiers en utilisant différents composants&amp;nbsp;:
&quot;file://&quot; pour un système de fichier local, ou &quot;ftp://&quot; pour attaquer un serveur ftp.
&lt;br /&gt;
Quelques options de base&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;possibilité de supprimer ou non le fichier&lt;/li&gt;
&lt;li&gt;intervalle de temps entre 2 &quot;poll&quot; du répertoire&lt;/li&gt;
&lt;li&gt;filtrer les fichiers qui seront récupérés sur leur nom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On peut facilement imaginer recopier en local des fichiers présents sur un ftp, avec une route de la forme&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
from(&amp;quot;ftp://192.168.2.42/folder/&amp;quot;)
.beanRef(&amp;quot;theBean&amp;quot;) // traitement du fichier (ajout/suppression de données ?)
.to(&amp;quot;file://C:\tmp&amp;quot;);
&lt;/pre&gt;


&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;ins&gt;CRON&lt;/ins&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.wikipedia.org/wiki/Crontab&quot;&gt;http://fr.wikipedia.org/wiki/Crontab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.ubuntu-fr.org/cron&quot;&gt;http://doc.ubuntu-fr.org/cron&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;ins&gt;Camel&lt;/ins&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://camel.apache.org/&quot;&gt;http://camel.apache.org/&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;avec son indispensable page des composants&amp;nbsp;: &lt;a href=&quot;http://camel.apache.org/components.html&quot;&gt;http://camel.apache.org/components.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/02/11/Comment-scanner-des-r%C3%A9pertoires#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/02/11/Comment-scanner-des-r%C3%A9pertoires#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/215</wfw:commentRss>
      </item>
    
  <item>
    <title>[Spring] Gestion des propriétés et des messages</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/12/17/%5BSpring%5D-Gestion-des-proprietes-et-des-messages</link>
    <guid isPermaLink="false">urn:md5:8fd627113fa0dde62ebc3057317e407d</guid>
    <pubDate>Fri, 17 Dec 2010 15:30:00 +0100</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>Spring</category>    
    <description>&lt;p&gt;Dans ce billet je vais faire un rapide aperçu d'une des manières de gérer les messages et les propriétés d'un projet avec Spring.&lt;/p&gt;    &lt;p&gt;Généralement, les messages sont stockés dans des fichiers &lt;em&gt;properties&lt;/em&gt; inclus dans le projet.&lt;/p&gt;


&lt;p&gt;Il y a deux manières de déclarer les fichiers &lt;em&gt;properties&lt;/em&gt;, selon les besoins d'utilisation des propriétés.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Placeholder&lt;/h3&gt;


&lt;p&gt;Il arrive souvent que des propriétés techniques aient besoin d'être injectées dans des beans par Spring.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;bean id=&amp;quot;testBean&amp;quot; class=&amp;quot;com.netapsys.Bean&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;adress&amp;quot; value=&amp;quot;${server.adress}&amp;quot; /&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Dans cet exemple, la propriété &lt;code&gt;server.adress&lt;/code&gt; est stockée dans un fichier &lt;em&gt;properties&lt;/em&gt;, et sera injectée par Spring au démarrage du serveur.&lt;/p&gt;


&lt;p&gt;La liste des fichiers dans lesquels Spring ira rechercher ces propriétés est à définir dans un bean de type &lt;code&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/2.0.x/api/index.html?org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html&quot; hreflang=&quot;fr&quot;&gt;PropertyPlaceholderConfigurer&lt;/a&gt;&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;propertyConfigurer&amp;quot; class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;
          &amp;lt;list&amp;gt;
               &amp;lt;value&amp;gt;classpath:/config/project.properties&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;classpath:/config/ldap.properties&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;file:/etc/netapsys/config.properties&amp;lt;/value&amp;gt; &amp;lt;!-- Les propriétés peuvent être surchargées dans un fichier présent sur le système. --&amp;gt;
          &amp;lt;/list&amp;gt;
     &amp;lt;/property&amp;gt;
     &amp;lt;property name=&amp;quot;ignoreResourceNotFound&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt; &amp;lt;!-- Permet de ne pas avoir d'erreur si un fichier n'est pas présent. --&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

&lt;p&gt;À noter qu'il est possible de définir plusieurs beans de type PropertyPlaceholderConfigurer, et de customiser la syntaxe du placeholder (qui est par défaut &lt;code&gt;${key}&lt;/code&gt;).&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;MessageSource&lt;/h3&gt;


&lt;p&gt;Pour récupérer des messages depuis le code (en récupérant le contexte Spring grâce à la classe &lt;code&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/context/ApplicationContext.html&quot; hreflang=&quot;fr&quot;&gt;ApplicationContext&lt;/a&gt;&lt;/code&gt;), ou pour les afficher dans les JSP grâce au tag &lt;code&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/1.2.x/taglib/tag/MessageTag.html&quot; hreflang=&quot;fr&quot;&gt;spring:message&lt;/a&gt;&lt;/code&gt;, il faut définir un bean &lt;code&gt;messageSource&lt;/code&gt; étendant la classe &lt;code&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/context/support/AbstractMessageSource.html&quot; hreflang=&quot;fr&quot;&gt;AbstractMessageSource&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;bean id=&amp;quot;messageSource&amp;quot; class=&amp;quot;org.springframework.context.support.ResourceBundleMessageSource&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;basenames&amp;quot;&amp;gt; &amp;lt;!-- Liste des fichiers à utiliser, présents dans le classpath. --&amp;gt;
          &amp;lt;list&amp;gt;
               &amp;lt;value&amp;gt;ErrorResources&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;LabelResources&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;config/project&amp;lt;/value&amp;gt;
          &amp;lt;/list&amp;gt;
     &amp;lt;/property&amp;gt;
     &amp;lt;property name=&amp;quot;alwaysUseMessageFormat&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;!-- Formatage de tous les messages. --&amp;gt;
     &amp;lt;property name=&amp;quot;useCodeAsDefaultMessage&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt; &amp;lt;!-- Utilise le code en tant que valeur par défaut. --&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Cette implémentation est la plus simple, et convient dans la majorité des cas. Cependant dans certains projets, le client peut vouloir changer certains messages ou propriétés sans avoir à redémarrer le serveur. Or, comme indiqué, la classe &lt;code&gt;ResourceBundleMessageSource&lt;/code&gt; se base sur la classe &lt;code&gt;&lt;a href=&quot;http://download.oracle.com/javase/1.5.0/docs/api/java/util/ResourceBundle.html&quot; hreflang=&quot;fr&quot;&gt;ResourceBundle&lt;/a&gt;&lt;/code&gt; du JDK, qui ne permet pas le rechargement des messages à chaud.&lt;/p&gt;


&lt;p&gt;Dans ce cas il faut se tourner vers une autre implémentation de Spring&amp;nbsp;: &lt;code&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html&quot; hreflang=&quot;fr&quot;&gt;ReloadableResourceBundleMessageSource&lt;/a&gt;&lt;/code&gt;. La déclaration sera quelque peu différente&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;messageSource&amp;quot; class=&amp;quot;org.springframework.context.support.ReloadableResourceBundleMessageSource&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;basenames&amp;quot;&amp;gt; &amp;lt;!-- Liste des fichiers à utiliser, présents dans le classpath. --&amp;gt;
          &amp;lt;list&amp;gt;
               &amp;lt;value&amp;gt;file:/etc/netapsys/config&amp;lt;/value&amp;gt; &amp;lt;!-- Les propriétés peuvent être surchargées dans un fichier présent sur le système (premier élément de la liste !).  --&amp;gt;
               &amp;lt;value&amp;gt;classpath:ErrorResources&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;classpath:LabelResources&amp;lt;/value&amp;gt;
               &amp;lt;value&amp;gt;classpath:config/project&amp;lt;/value&amp;gt;
          &amp;lt;/list&amp;gt;
     &amp;lt;/property&amp;gt;
     &amp;lt;property name=&amp;quot;alwaysUseMessageFormat&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;!-- Formatage de tous les messages. --&amp;gt;
     &amp;lt;property name=&amp;quot;useCodeAsDefaultMessage&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt; &amp;lt;!-- Utilise le code en tant que valeur par défaut. --&amp;gt;
     &amp;lt;property name=&amp;quot;cacheSeconds&amp;quot; value=&amp;quot;10&amp;quot; /&amp;gt; &amp;lt;!-- Taux de rafraîchissement des messages mis en cache. --&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Contrairement à la première implémentation, il est maintenant possible d'indiquer un fichier présent sur le système, dans lequel notre client ira surcharger les messages voulus par exemple.
Petite explication de la propriété &lt;code&gt;cacheSeconds&lt;/code&gt;&amp;nbsp;: lors de l'affichage d'un message, il est mis dans un cache. Si la clé du message est redemandée après &quot;&lt;code&gt;cacheSeconds&lt;/code&gt;&quot; secondes, le bundle ira revérifié dans les fichiers properties si sa valeur n'a pas changée.&lt;/p&gt;


&lt;p&gt;De plus, cette implémentation peut aussi être intéressante à utiliser dans le cadre du développement, lors de la construction des IHM.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/12/17/%5BSpring%5D-Gestion-des-proprietes-et-des-messages#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/12/17/%5BSpring%5D-Gestion-des-proprietes-et-des-messages#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/193</wfw:commentRss>
      </item>
    
  <item>
    <title>[Hibernate] - Persistance de types personnalisés</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/12/10/%5BHibernate%5D-Persistance-de-types-personnalises</link>
    <guid isPermaLink="false">urn:md5:aa0c096254bb7977e724bb6827e34a4d</guid>
    <pubDate>Fri, 10 Dec 2010 18:30:00 +0100</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>Hibernate</category><category>JPA</category><category>UserType</category>    
    <description>&lt;p&gt;Dans ce billet, nous allons voir comment Hibernate nous permet simplement, et de façon transparente, de persister des types Java qui ne sont pas gérés nativement par la base de données. Nous verrons aussi l'utilisation avec JPA.&lt;/p&gt;    &lt;p&gt;Dans une application, la persistance des données et leur gestion par la couche DAO sont transparentes tant que les types manipulés sont gérés nativement par Hibernate (les nombres en général, chaînes de caractères, dates, données binaires). S'il y a besoin d'utiliser d'autres types de données, il y a généralement des &quot;mappers&quot; mis en place pour faire la conversion entre le type voulu et un type géré par Hibernate et le SGBD.&lt;/p&gt;


&lt;p&gt;Hibernate met à disposition l'interface &lt;code&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/usertype/UserType.html&quot; hreflang=&quot;fr&quot;&gt;UserType&lt;/a&gt;&lt;/code&gt;, permettant de spécifier un mapper qu'il utilisera pour persister et transformer les types voulus.&lt;/p&gt;


&lt;p&gt;Nous allons voir un exemple avec une classe possédant un attribut de type &lt;code&gt;&lt;a href=&quot;http://download.oracle.com/javase/6/docs/api/java/awt/Color.html&quot; hreflang=&quot;fr&quot;&gt;Color&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Commençons par décrire notre classe, sans information Hibernate pour l'instant&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
/** Classe de test symbolisant un groupe.
 * @author Netapsys
 */
public class Groupe {
    /** Identifiant du groupe. */
    private Integer id;

    /** Couleur du groupe. */
    private Color couleur;

    // Getters et setters...
}
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;ColorUserType.java&lt;/h3&gt;


&lt;p&gt;Sans la classe fournie par Hibernate, il aurait fallu gérer la couleur avec des Integer, et faire le mapping vers la classe Color à divers endroits du code.&lt;br /&gt;
Dans le contrat imposé par l'interface &lt;code&gt;UserType&lt;/code&gt;, seules quatre méthodes vont nous intéresser&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;int&lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2010/12/10/&quot;&gt;&lt;/a&gt; sqlTypes();&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Indique sous quel type SQL sera stocké notre type personnalisé. Le type retourné doit correspondre au type de colonne de la base de données.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
/** {@inheritDoc} */
@Override
public int[] sqlTypes() {
    return new int[] {Types.INTEGER }; // Notre couleur sera stockée sous forme d'entier.
}
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Class returnedClass();&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Indique la classe de notre type personnalisé.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
/** {@inheritDoc} */
@Override
public Class&amp;lt;Color&amp;gt; returnedClass() {
    return Color.class;
}
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;En charge de convertir notre type personnalisé en type de donnée SQL, indiqué dans la méthode &lt;code&gt;sqlTypes()&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
/** {@inheritDoc} */
@Override
public void nullSafeSet(final PreparedStatement st, final Object value, final int index)
  throws HibernateException, SQLException {
    if (null == value) {
        st.setNull(index, Types.INTEGER);
    } else {
        final Color color = (Color) value;
        st.setInt(index, color.getRGB()); // on stocke en base la valeur RGB de la couleur.
    }
}
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Object nullSafeGet(ResultSet rs, String&lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2010/12/10/&quot;&gt;&lt;/a&gt; names, Object owner) throws HibernateException, SQLException;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;En charge de convertir la donnée récupérée de la base dans le type souhaité, indiqué dans la méthode &lt;code&gt;returnedClass()&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
/** {@inheritDoc} */
@Override
public Object nullSafeGet(final ResultSet rs, final String[] names, final Object owner)
  throws HibernateException, SQLException {
    final Integer value = (Integer) Hibernate.INTEGER.nullSafeGet(rs, names[0]); // on récupère la valeur RGB de la couleur.
    if (value != null) {
        return new Color(value);
    } else {
        return null;
    }
}
&lt;/pre&gt;


&lt;p&gt;Une classe d'exemple, jointe à ce billet, contient les autres méthodes.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Déclaration Hibernate&lt;/h3&gt;


&lt;p&gt;Si le mapping Hibernate est fait avec des fichiers XML, il faut rajouter l'attribut &lt;code&gt;type&lt;/code&gt; à la balise &lt;code&gt;property&lt;/code&gt; de l'attribut que nous voulons mapper. Il faut indiquer à cet attribut le nom complet de la classe de mapping&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;property name=&amp;quot;couleur&amp;quot; column=&amp;quot;grp_color&amp;quot; type=&amp;quot;com.netapsys.ColorUserType&amp;quot; /&amp;gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Déclaration JPA&lt;/h3&gt;


&lt;p&gt;Si le mapping est fait grâce aux annotations JPA, il suffit de rajouter l'annotation &lt;code&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/annotations/Type.html&quot; hreflang=&quot;fr&quot;&gt;@Type&lt;/a&gt;&lt;/code&gt; avec le nom complet de la classe de mapping sur l'attribut à mapper&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
@Type(type = &amp;quot;com.netapsys.ColorUserType&amp;quot;)
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;L'utilisation de ce mapping &quot;automatique&quot; permet de grandement simplifier le reste du code en évitant&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;de mélanger deux types différents pour la même donnée&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;d'avoir à passer d'un type à l'autre à différents endroits du code, souvent source de duplication.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;br /&gt;
Vous trouverez en pièce jointe une archive contenant le code&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de la classe &lt;code&gt;Groupe&lt;/code&gt; sans annotation&amp;nbsp;: &lt;code&gt;Groupe.java&lt;/code&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;du fichier de mapping Hibernate de la classe &lt;code&gt;Groupe&lt;/code&gt;&amp;nbsp;: &lt;code&gt;groupe.hbm.xml&lt;/code&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;de la classe &lt;code&gt;GroupeJpa&lt;/code&gt;, correspondant au bean &lt;code&gt;Groupe&lt;/code&gt; avec les annotations JPA&amp;nbsp;: &lt;code&gt;GroupeJpa.java&lt;/code&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;de la classe &lt;code&gt;ColorUserType&lt;/code&gt; réalisant le mapping&amp;nbsp;: &lt;code&gt;ColorUserType.java&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
    
          <enclosure url="http://blog.netapsys.fr/public/code/Hibernate-UserType.zip"
      length="3012" type="application/zip" />
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/12/10/%5BHibernate%5D-Persistance-de-types-personnalises#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/12/10/%5BHibernate%5D-Persistance-de-types-personnalises#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/191</wfw:commentRss>
      </item>
    
  <item>
    <title>[Nantes JUG] - 25 novembre 2010 - Soirée RIA : Flex, HTML5</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/11/19/%5BNantes-JUG%5D-25-novembre-2010-Soiree-RIA-%3A-Flex-HTML5</link>
    <guid isPermaLink="false">urn:md5:d87cb36479d51178c3c0c7a7fbe9c400</guid>
    <pubDate>Fri, 19 Nov 2010 18:05:00 +0100</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Netapsys</category>
        <category>JUG</category><category>Nantes JUG</category>    
    <description>&lt;p&gt;&lt;br /&gt;
En tant que partenaire du JUG (Java User Group) de Nantes, Netapsys vous invite à la conférence du jeudi 25 novembre 2010, de 19h à 21h, à &lt;a href=&quot;http://www.mines-nantes.fr/fr/Pratique/Venir-a-l-Ecole&quot; hreflang=&quot;fr&quot;&gt;l'école des Mines de Nantes&lt;/a&gt;. Elle sera animée par François Le Droff, d'Adobe France.&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;
Durant cette soirée, nous discuterons de RIA et Java&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de Flash, de Flex, d’HTML5&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;d’applications multi-écrans: desktop, tablette, téléphone, télévision&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;des solutions offertes par Adobe dans ce domaine&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;nous verrons comment les technologies Adobe permettent aux développeurs et architectes de construire des applications internet riches et multi-écrans, tout en faisant fructifier leurs anciens investissements, notamment sur les technologies Java/JavaEE (EJB3, Spring, Hibernate JPA, Maven...).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;ins&gt;À propos de François le Droff&lt;/ins&gt; :&lt;br /&gt;
Brestois d’origine, parisien d’adoption, François est architecte technique chez Adobe France depuis 2007, après 9 ans d’expérience dans le développement d’applications Web, principalement en Java/JavaEE. Acteur et contributeur de la communauté open source (qsos, xradar, fna), François est membre de l’OSSGTP (Open Source Software Get Together Paris), et du ParisJUG.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Pour vous inscrire à cette soirée, c'est &lt;a href=&quot;http://jugevents.org/jugevents/event/registration.form?event.id=31710&quot; hreflang=&quot;fr&quot;&gt;ICI&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
&lt;ins&gt;Résumé&lt;/ins&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Quoi&amp;nbsp;: &lt;a href=&quot;http://www.nantesjug.org/&quot; hreflang=&quot;fr&quot;&gt;http://www.nantesjug.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Quand&amp;nbsp;: Jeudi 25 novembre 2010, de 19h à 21h&lt;/li&gt;
&lt;li&gt;Où&amp;nbsp;: &lt;a href=&quot;http://www.mines-nantes.fr/fr/Pratique/Venir-a-l-Ecole&quot; hreflang=&quot;fr&quot;&gt;http://www.mines-nantes.fr/fr/Pratique/Venir-a-l-Ecole&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Comment&amp;nbsp;: &lt;a href=&quot;http://jugevents.org/jugevents/event/registration.form?event.id=31710&quot; hreflang=&quot;fr&quot;&gt;http://jugevents.org/jugevents/event/registration.form?event.id=31710&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/11/19/%5BNantes-JUG%5D-25-novembre-2010-Soiree-RIA-%3A-Flex-HTML5#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/11/19/%5BNantes-JUG%5D-25-novembre-2010-Soiree-RIA-%3A-Flex-HTML5#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/178</wfw:commentRss>
      </item>
    
  <item>
    <title>[Spring Security] Authentification LDAP + autorisations BDD</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/10/02/%5BSpring-Security%5D-Authentification-LDAP-autorisations-BDD</link>
    <guid isPermaLink="false">urn:md5:1ca94d795c9e0b31a3549ffa56341d4b</guid>
    <pubDate>Sat, 02 Oct 2010 14:56:00 +0200</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>Spring Security</category>    
    <description>&lt;p&gt;Ce besoin est assez courant dans le développement d'applications&amp;nbsp;: les utilisateurs sont présents dans un annuaire général, et c'est à chaque application de gérer ses droits d'accès.
La &lt;a href=&quot;http://static.springsource.org/spring-security/site/reference.html&quot; hreflang=&quot;fr&quot;&gt;documentation&lt;/a&gt; de Spring Security explique bien le fonctionnement général du framework, mais décrit principalement les cas nominaux que sont le &quot;tout LDAP&quot; et le &quot;tout BDD&quot;.
Je vais montrer ici les quelques points de configuration nécessaires afin de mélanger ces deux aspects.&lt;/p&gt;    &lt;p&gt;&lt;ins&gt;Pré-requis&lt;/ins&gt; :&lt;br /&gt;
- &lt;a href=&quot;http://static.springsource.org/spring-security/site/&quot; hreflang=&quot;fr&quot;&gt;Spring security&lt;/a&gt;&lt;br /&gt;
- &lt;a href=&quot;http://www.springsource.org/ldap&quot; hreflang=&quot;fr&quot;&gt;Spring ldap&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Je vais commencer par présenter les différentes briques qui vont nous servir à faire fonctionner le tout.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Tout d'abord, nous allons définir la connexion à notre annuaire&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;contextSource&amp;quot; class=&amp;quot;org.springframework.security.ldap.DefaultSpringSecurityContextSource&amp;quot;&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;0&amp;quot; value=&amp;quot;ldap.example.com:389/dc=netapsys,dc=com&amp;quot; /&amp;gt;
	&amp;lt;!--&amp;lt;property name=&amp;quot;userDn&amp;quot; value=&amp;quot;cn=manager,dc=netapsys,dc=com&amp;quot; /&amp;gt;--&amp;gt;
	&amp;lt;!--&amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;password&amp;quot; /&amp;gt;--&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Ici, nous utilisons une connexion anonyme à l'annuaire, si une athentification est nécessaire, il suffit de décommenter les deux lignes.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Ensuite nous allons définir un objet capable de faire la recherche dans l'annuaire&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;ldapUserSearch&amp;quot; class=&amp;quot;org.springframework.security.ldap.search.FilterBasedLdapUserSearch&amp;quot;&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;0&amp;quot; value=&amp;quot;ou=personnes&amp;quot; /&amp;gt; &amp;lt;!-- Branche principale à partir de laquelle faire la recherche --&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;1&amp;quot; value=&amp;quot;(uid={0})&amp;quot; /&amp;gt; &amp;lt;!-- Critère de recherche LDAP, ici le login de l'utilisateur correspond à l'uid de l'entrée LDAP --&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;2&amp;quot; ref=&amp;quot;contextSource&amp;quot; /&amp;gt;
	&amp;lt;property name=&amp;quot;searchSubtree&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;!-- Recherche dans les sous-branches --&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Enfin, nous allons définir notre propre classe de gestion des droits&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;netapsysAuthoritiesPopulator&amp;quot; class=&amp;quot;com.netapsys.security.NetapsysAuthoritiesPopulator&amp;quot; /&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Petit artifice, bien que cette classe ait pour but de récupérer les autorisations en base de données, elle doit étendre la classe &lt;code&gt;LdapAuthoritiesPopulator&lt;/code&gt; du framework. Notons qu'arrivés à ce stade, nous sommes sûrs que l'utilisateur est authentifié.&lt;/p&gt;
&lt;pre&gt;
/** Classe permettant de récupérer les droits d'un utilisateur se connectant à l'application.&amp;lt;br /&amp;gt;
 * Si le login n'existe pas en base, alors l'utilisateur a par défaut les droits d'un invité. */
public class NetapsysAuthoritiesPopulator implements LdapAuthoritiesPopulator
{
    /** Service des utilisateurs. */
    @Resource(name = &amp;quot;utilisateurService&amp;quot;) private UtilisateurService utilisateurService;

    /** {@inheritDoc} */
    @Override public Collection&amp;lt;GrantedAuthority&amp;gt; getGrantedAuthorities(final DirContextOperations userData, final String username) {
        final List&amp;lt;GrantedAuthority&amp;gt; authorities = new ArrayList&amp;lt;GrantedAuthority&amp;gt;();
        final Utilisateur user = this.utilisateurService.getByLogin(username);	// Recherche de l'utilisateur en base
        if (user == null) {
            authorities.add(new GrantedAuthorityImpl(&amp;quot;ROLE_GUEST&amp;quot;));
        } else {
            authorities.add(new GrantedAuthorityImpl(user.getProfil().getRole()));
        }
        return authorities;
    }

    /** Setter pour utilisateurService.
     * @param utilisateurService le utilisateurService à écrire. */
    public void setUtilisateurService(final UtilisateurService utilisateurService) {
        this.utilisateurService = utilisateurService;
    }
}
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Assemblons maintenant toutes ces parties&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;ldapAuthProvider&amp;quot; class=&amp;quot;org.springframework.security.ldap.authentication.LdapAuthenticationProvider&amp;quot;&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;0&amp;quot;&amp;gt;
		&amp;lt;bean class=&amp;quot;org.springframework.security.ldap.authentication.BindAuthenticator&amp;quot;&amp;gt;
			&amp;lt;constructor-arg index=&amp;quot;0&amp;quot; ref=&amp;quot;contextSource&amp;quot; /&amp;gt;
			&amp;lt;property name=&amp;quot;userSearch&amp;quot; ref=&amp;quot;ldapUserSearch&amp;quot; /&amp;gt;
		&amp;lt;/bean&amp;gt;
	&amp;lt;/constructor-arg&amp;gt;
	&amp;lt;constructor-arg index=&amp;quot;1&amp;quot;&amp;gt;
		&amp;lt;bean ref=&amp;quot;netapsysAuthoritiesPopulator&amp;quot; /&amp;gt;
	&amp;lt;/constructor-arg&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Nous n'avons plus qu'à injecter ce provider au gestionnaire de sécurité de notre application&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;security:authentication-manager&amp;gt;
	&amp;lt;security:authentication-provider ref=&amp;quot;ldapAuthProvider&amp;quot; /&amp;gt;
&amp;lt;/security:authentication-manager&amp;gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Et le tour est joué&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;
Vous trouverez en pièce jointe un fichier de configuration Spring d'exemple.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description>
    
          <enclosure url="http://blog.netapsys.fr/public/SpringSecurity/spring-example.xml"
      length="2568" type="application/xml" />
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/10/02/%5BSpring-Security%5D-Authentification-LDAP-autorisations-BDD#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/10/02/%5BSpring-Security%5D-Authentification-LDAP-autorisations-BDD#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/175</wfw:commentRss>
      </item>
    
  <item>
    <title>Générer le diagramme de séquence de votre application</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/05/28/Diagramme-de-sequence-de-navigation</link>
    <guid isPermaLink="false">urn:md5:b962648ab89ec0fed6a0f281c6e274a4</guid>
    <pubDate>Wed, 02 Jun 2010 10:15:00 +0200</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>Diagramme de séquence</category><category>java</category><category>tomcat</category><category>UML</category>    
    <description>&lt;p&gt;Nous allons voir l'utilisation, avec tomcat, de &lt;strong&gt;jtracert&lt;/strong&gt;, outil géré par Google permettant de générer le diagramme de séquence d'une application Java, en fonction de votre navigation sur celle-ci.&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;
- Nous allons commencer par récupérer l'archive de l'application&amp;nbsp;: &lt;a href=&quot;http://code.google.com/p/jtracert/&quot; hreflang=&quot;fr&quot;&gt;jTracert-x.x.x.zip&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;- Dézipper l'archive.&lt;/p&gt;


&lt;p&gt;- Editer le fichier &lt;strong&gt;catalina.bat&lt;/strong&gt; ou &lt;strong&gt;catalina.sh&lt;/strong&gt; du serveur tomcat.&lt;/p&gt;


&lt;p&gt;- À la ligne définissant les paramètres Java (&lt;em&gt;JAVA_OPTS&lt;/em&gt;), rajouter le paramètre suivant&amp;nbsp;: &lt;code&gt;-javaagent:&amp;lt;chemin vers jtracert&amp;gt;\jTracert.jar=7007&lt;/code&gt;&lt;/p&gt;


&lt;p&gt;- Lancer le serveur tomcat (sans oublier de copier notre application dans le dossier &lt;em&gt;webapps&lt;/em&gt;)&amp;nbsp;: &lt;strong&gt;startup.bat&lt;/strong&gt; ou  &lt;strong&gt;startup.sh&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;- Le message suivant apparaît dans la console du serveur&amp;nbsp;: &lt;code&gt;Waiting for a connection from jTracert GUI on port 7007&lt;/code&gt;&lt;/p&gt;


&lt;p&gt;- Lancer jtracert&amp;nbsp;: &lt;img src=&quot;http://blog.netapsys.fr/public/images/jtracert/jtracert1.png&quot; alt=&quot;Configuration jtracert&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;
1. Répertoire de destination des fichiers générés&lt;br /&gt;
2. Nom du package des classes qui seront filtrées lors de la génération&lt;br /&gt;
3. Adresse du serveur tomcat&lt;br /&gt;
4. Port d'écoute&lt;br /&gt;
5. Paramètre à ajouter dans le fichier catalina&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;- Se connecter, le serveur tomcat démarre.&lt;/p&gt;


&lt;p&gt;- Connectez-vous à l'application et naviguez. Jtracert génère les diagrammes en fonction du filtre appliqué.&lt;/p&gt;


&lt;p&gt;- L'arborescence de gauche contient les les différentes classes qui ont été appelées, avec le nom de la méthode d'entrée&amp;nbsp;: &lt;img src=&quot;http://blog.netapsys.fr/public/images/jtracert/jtracert-arbo.png&quot; alt=&quot;jtracert-Arborescence&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;- Le détail de l'appel d'une classe donne le diagramme de séquence correspondant&amp;nbsp;: &lt;img src=&quot;http://blog.netapsys.fr/public/images/jtracert/.jtracert-sd_m.jpg&quot; alt=&quot;jtracert-Diagramme&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;- Bien qu'il soit possible d'affiche le diagramme en plein écran, sa lecture, et surtout son partage, ne sont pas aisés. C'est pourquoi jtracert propose de l'exporter dans un fichier image (s'il n'est pas trop grand), ou pdf.
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Lors de l'arrivée sur un projet, jtracert apporte une vue d'ensemble au fonctionnement de l'application. Il permet donc de remplacer, ou au moins de précéder, une longue et fastidieuse phase de debug.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/05/28/Diagramme-de-sequence-de-navigation#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/05/28/Diagramme-de-sequence-de-navigation#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/157</wfw:commentRss>
      </item>
    
  <item>
    <title>[Eclipse] Working set</title>
    <link>http://blog.netapsys.fr/index.php/post/2010/04/22/%5BEclipse%5D-Working-set</link>
    <guid isPermaLink="false">urn:md5:19cb31b434da1eb7ce1c378a8dc6d07c</guid>
    <pubDate>Thu, 22 Apr 2010 22:57:00 +0200</pubDate>
    <dc:creator>Benoît Cotinat</dc:creator>
        <category>Java J2EE</category>
        <category>eclipse working set</category>    
    <description>&lt;p&gt;Petit point sur une notion d'eclipse&amp;nbsp;: les &quot;working set&quot;. Cela permet de créer nos propres environnements de travail au sein de l'IDE, en filtrant les éléments voulus (et donc enlever, entre autre, le répertoire &quot;target&quot;).
Ils sont utilisés dans plusieurs recherches et vues.&lt;/p&gt;    &lt;h3&gt;Création d'un working set&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&quot;Window&quot; -&amp;gt; &quot;Working Sets&quot; -&amp;gt; &quot;Edit...&quot; -&amp;gt; &quot;New...&quot; -&amp;gt; &quot;Java&quot;&lt;/li&gt;
&lt;li&gt;Dérouler votre projet et ne cocher/sélectionner que les composants qui vous intéressent&lt;/li&gt;
&lt;li&gt;Donner un nom au working set -&amp;gt; &quot;Finish&quot;&lt;/li&gt;
&lt;li&gt;Cocher le working set créé et valider&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vous pouvez bien évidemment créer plusieurs working set pour un même projet eclispe.&lt;/p&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Filtrer les recherches&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Search (Ctrl+H)
&lt;ol&gt;
&lt;li&gt;Dans la partie &quot;Scope&quot;, sélectionner &quot;Working set&quot;, puis cliquer sur &quot;Choose&quot;&lt;/li&gt;
&lt;li&gt;Cocher le working set créé et valider par OK&lt;/li&gt;
&lt;li&gt;Faites votre recherche, elle ne s'effectuera que dans les dossiers que vous avez sélectionnés&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Open Resource/Open Type (Ctrl+Shift+R/Ctrl+Shift+T)
&lt;ul&gt;
&lt;li&gt;Accéder au menu de la fenêtre (petite flèche vers le bas) -&amp;gt; &quot;Select Working Set&quot;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Filtrer les vues (Package explorer, Navigator, Hierarchy, Breakpoints, ...)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accéder au menu de la vue (petite flèche vers le bas) -&amp;gt; &quot;Select Working Set&quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
Pour revenir au workspace&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accéder au menu de la vue -&amp;gt; &quot;Deselect Working Set&quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
Et il est aussi possible de n'afficher qu'un projet (ou partie du projet) du workspace (indépendemment des working set)&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clique-droit sur le projet (ou son composant) -&amp;gt; &quot;Go Into&quot;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2010/04/22/%5BEclipse%5D-Working-set#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2010/04/22/%5BEclipse%5D-Working-set#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/148</wfw:commentRss>
      </item>
    
</channel>
</rss>
