Formulaire css sans tableau

27 fĂ©vrier 2008 – 7:44

La présentation des formulaires est souvent synonyme de casse tête. Réussir à positionner l’ensemble de ces éléments est souvent obtenu au détriment des standards. Cet article va vous présenter une manière de parvenir à vos fins, tout en respectant les normes du W3C.

Fieldset, legend et label : des balises qui gagneraient Ă  ĂŞtre connues

En dehors des élements FORM, INPUT, TEXTAREA, SELECT, il existe des balises html méconnues :

Label : Cet élément permet de légender un élément de saisie, sans sa présence, des personnes malvoyantes ne pourraient pas le remplir.

Fieldset : il permet de séparer le formulaire en groupes distincts, par exemple une première partie concernera la civilité, la seconde l’adresse.

Legend : il va de pair avec le fieldset, celui-ci servira à décrire le contenu du groupe d’éléments.

Maintenant que les présentations sont faites, entrons dans le vif du sujet, le code html du formulaire.

La première mouture, réalisée sans trucage et sans CSS ne donne pas très envie, nous allons y remédier très bientôt.

Code html du formaire :

formulaire-sans-css.gif

  1. <legend>Civilité</legend>
  2.         <li>CivilitĂ©
  3. <select id=“civilite” name=“civilite”> <option value=“1″>Monsieur</option> <option value=“2″>Madame</option> <option value=“3″>Mademoiselle</option> </select></li>
  4.         <li><label>Nom : </label>
  5. <input name=“nom” /></li>
  6.         <li><label>PrĂ©nom</label>
  7. <input name=“prenom” /></li>
  8.         <li><label>Nom de jeune fille</label>
  9. <input name=“nomjf” /></li>
  10. </ul>
  11. </fieldset>
  12. <legend>Coordonées</legend>
  13.         <li><label>N° et rue</label>
  14. <input name=“voie” /></li>
  15.         <li><label>complĂ©ment d’adresse</label>
  16. <input name=“cmplvoie” /></li>
  17.         <li><label>Code postal</label>
  18. <input name=“codepostal” /></li>
  19.         <li><label>ville</label>
  20. <input name=“ville” /></li>
  21.         <li> <input type=“submit” value=“Valider” /></li>
  22. </ul>
  23. </fieldset>
  24. </form>

L’utilisation des balises <li> (affichage par block) nous permet de positionner les Ă©lĂ©ments au dessous des autres et non inline (”Ă€ la queue leu leu”). Les puces ne sont pas très jolies, ni utiles, nous allons donc les cacher avec

  1. form{
  2. width:450px ;
  3. }
  4. li{
  5. list-style-type : none ;
  6. clear:both ;
  7. line-height:25px ;
  8. }
  9. body{
  10. font-family :<span class=“code-quote”>“Trebuchet MS”</span>,Verdana,Geneva,Arial,Helvetica,sans-serif ;
  11. font-size:small ;
  12. margin:2em 1% ;
  13. padding:0 ;
  14. }
  15. label{
  16. display:block ;
  17. <span class=“code-object”>float</span>:left ;
  18. width:140px ;
  19. }
  20. input, select{
  21. display:block ;
  22. <span class=“code-object”>float</span>:left ;
  23. width:200px ;
  24. }
  25. #submit{
  26. margin-right:42px ;
  27. <span class=“code-object”>float</span>:right ;
  28. width:75px ;
  29. border:1px solid black ;
  30. }

L’astuce pour afficher correctement les label et les input c’est de les dĂ©clarer en display:block afin de pouvoir leur attribuer une width float left permet de les afficher les uns Ă  cotĂ©s des autres, et le fait de positionner un clear:both sur les li permet de repartir au dĂ©but de la ligne après chaque balise ouvrant li
formulaire-avec-css-sans-tableau.gif

Bon, ca n’est pas très sexy, mais je vous invite Ă  les modifier selon vos goĂ»ts via le zip fourni
formulaire-css-sans-tableaurar.zip

jmx : supervision et administration des applications J2EE

27 fĂ©vrier 2008 – 7:41

jmx-instrumentation-supervision.jpg

Java Management eXtension ou JMX est une API java permettant de surveiller une application existante. Cette technologie permet également d’intéragir sur l’application en cours d’exécution. Cette API a été intégré dans le J2SE à partir de la version 1.5. Dans l’exemple ci-dessous, nous utiliserons cette technologie afin de suivre le nombre d’objets mis en cache avec EHCache et JMX .

Acquisition de données (instrumentation) avec JMX

Le MBean (managed bean) est l’élément de base de JMX. Associé à un agent de supervision, il servira d’interface de communication avec les éléments gérés par JMX. On peut le voir comme une sonde effectuant une ou plusieurs mesures.

MBeanServer : l’agent de Supervision

Appelés agents ou serveurs JMX, ceux-ci sont chargés de recenser les MBeans. Chaque ajout ou supression d’un MBean donne lieu à une notification.

Spring et JMX

Comme à son habitude, Spring facilite l’intégration de JMX dans l’architecture d’une application. Il met à disposition des méthodes simples pour enregistrer de nouveaux MBean. Cette intégration se fait tout en conservant un faible couplage de l’application avec cette technologie.

Suivi des objets en cache avec EHCACHE et JMX dans une application SPRING

Afin de faciliter la mise en place de cette technologie, nous nous baserons sur une application fonctionnant sur le serveur d’application JBOSS.

Nous allons mettre un place un MBean qui effectuera un certain nombre de mesures afin de suivre l’évolution de la propriété MemoryStoreSize de notre cache.

Configuration Spring du MBean :

  1. <bean id=“jmxCacheBean” class=“com.programmetvcesoir.jmx.JmxCache”></bean>
  2.  
  3. <property name=“cacheManager” ref=“cacheManagerID”></property>

La classe correspondante :

  1. mport net.sf.ehcache.Cache ;
  2. import net.sf.ehcache.CacheManager ;/**
  3. * MBean permettant de surveiller et d‘adminitrer via jmx le cache gĂ©rĂ© par EHCACHE
  4. * @author cestpasdur
  5. *
  6. */
  7. public class JmxCache
  8. /**
  9. * Manager de cache EHCACHE
  10. */
  11. private CacheManager cacheManager ;public JmxCache()public long getMemoryStoreSize()Cache cache=cacheManager.getCache("1000_overflow_disk") ;
  12. return cache.getMemoryStoreSize() ;public void removeAll()Cache cache=cacheManager.getCache("1000_overflow_disk") ;
  13. cache.removeAll() ;
  14. public void setCacheManager(CacheManager cacheManager)
  15. this.cacheManager = cacheManager ;

Comme vous pouvez le voir, la valeur de la propriĂ©tĂ© cacheManager est injectĂ©e via la configuration Spring. Nous avons donc accès dans notre MBean Ă  l’ensemble des propriĂ©tĂ©s du cacheManager, en l’occurence celle qui nous intĂ©resse : memoryStoreSize (nombre d’objet en cache Ă  un instant T).
Maintenant, notre MBean a besoin de communiquer avec un MBeanServer. La configuration suivante permet de localiser un server existant et de s’y connecter (dans notre cas, JBoss)

  1. <bean id=“mbeanServer” class=“org.springframework.jmx.support.MBeanServerFactoryBean”></bean>
  2.  
  3. <property name=“locateExistingServerIfPossible” value=“true”></property>

C’est aussi simple que çà !Notre MBean va devoir notifier sa prĂ©sence au MBeanServer en utilisant un MBeanExporter :

  1. <bean id=“exporter” class=“org.springframework.jmx.export.MBeanExporter”></bean>
  2. <property name=“beans”> <map>             <entry key=“bean:name=jmxCacheBean” value-ref=“jmxCacheBean”>
  3. </entry></map> </property>
  4. <property name=“server” ref=“mbeanServer”></property>

Au démarrage du serveur, nous pouvons voir la présence du MBean dans les logs :

[STDOUT] [2007-10-23 17:02:31][main] DEBUG org.springframework.jmx.support.JmxUtils - Found MBeanServer : org.jboss.mx.server.MBeanServerImpl@1c9a690[ defaultDomain='jboss' ]
17:02:31,375 INFO [STDOUT] [2007-10-23 17:02:31][main] INFO org.springframework.jmx.export.MBeanExporter - Registering beans for JMX exposure on startup
17:02:31,375 INFO [STDOUT] [2007-10-23 17:02:31][main] DEBUG org.springframework.jmx.export.MBeanExporter - Located simple bean ‘bean:name=jmxCacheBean’ : registering with JMX server as MBean [bean:name=jmxCacheBean]

Voyons voir maintenant le rĂ©sultat avec la console web JMX de JBoss. Vous pouvez constater que notre MBean est bien rĂ©fĂ©rencĂ© sur le serveur d’applications.jmx-console-jboss-jmx-cache.pngtilisons maintenant une console JMX un peu plus pratique, vous avez la JConsole disponible via le jdk, dans mon cas c’est ici : c :\Program Files\Java\jdk1.6.0_03\bin\jconsole.exe ou bien vous pouvez tĂ©lĂ©charger la MC4J management consoleVoici un aperçu du manager de cache dans la console MC4J :
jmx-mc4j-management-console-cache-manager.pngCette impression d’Ă©cran reprĂ©sente une mesure effectuĂ©e sur le nombre d’objets en cache pendant une courte pĂ©riode durant laquelle le cache a Ă©tĂ© rĂ©initialisĂ© via la mĂ©thode removeAll de notre MBean JmxCache

J’espère que cette petite introduction aux extensions JMX vous a permis de comprendre ce qu’est JMX, et, d’en cerner un peu plus l’utilitĂ©.

Java : Valider votre code html avec Jtidy

27 fĂ©vrier 2008 – 7:33

html-valide.jpg

Pour les adeptes de cet addon assez connu des développeurs web soucieux de leur conformité html, il existe également une version java de cet outil. Ce petit exemple de code montre comment parser la home de ce site, et également d’en afficher le rapport.

Un petit exemple simple ci dessous

  1. package com.cestpasdur ;
  2.  
  3. import java.io.IOException ;
  4. import java.io.InputStream ;
  5. import java.net.URL ;
  6. import java.net.URLConnection ;
  7. import org.w3c.tidy.Tidy ;
  8.  
  9. public class TidyTest
  10.  
  11. public static void main(String args) throws IOException
  12.  
  13. URL url = new URL(“http://www.cestpasdur.com/”);
  14. URLConnection urlConn = url.openConnection();
  15. InputStream inputStream = urlConn.getInputStream();
  16. Tidy tidy = new Tidy() ;
  17. tidy.setOnlyErrors(false) ;
  18. tidy.setXHTML(true) ;
  19. tidy.setShowWarnings(true) ;
  20. tidy.parse(inputStream, System.out);

Tel que c’est codĂ©, vous devriez voir que ce site, n’est pas exemplaire au niveau du code xhtml, mais on va dire que ce n’est pas le sujet de l’article.
Bon courage pour corriger votre code html

Evolution envisagée :

On peut imaginer brancher ce genre de chose a un sitemap afin de parser l’intĂ©gralitĂ© d’un site web et ainsi en gĂ©nĂ©rer un rapport complet.

EHCACHE : gestion du cache en JAVA/J2EE

26 fĂ©vrier 2008 – 23:53

ehcache.jpg

EHCACHE est un gestionnaire de cache JAVA/J2EE.

Le cache est chargĂ© de stocker dans un espace mĂ©moire rapide (la mĂ©moire vive) , le rĂ©sultat d’opĂ©rations obtenues Ă  partir d’une mĂ©moire principale qui est plus grande et plus lente (une base de donnĂ©es, un webservice, un fichier…).

Nous allons commencer par décrire les différentes options de configuration d’ehcache.

Installation de la librairie

  • Mettez le jar ehcache dans votre classpath (WEB-INF/lib/), version 1.3 pour cette article
  • Copiez y Ă©galement ses dĂ©pendances (Commons Logging, Commons collections)
  • Configurez ehcache.xml et mettez le Ă©galement dans votre classpath.

Configuration du cache via ehache.xml

Localisation des fichies temporaires :

Stockage des fichiers dans le répertoire temp du user exemple : C :\Documents and Settings\user\Local Settings\Temp

  1. <diskstore path=“java.io.tmpdir”>
  2. </diskstore>

Cache par défaut

Ces rĂ©glages seront appliquĂ©s au caches crĂ©es via la mĂ©thode CacheManager.add(”nom du cache”).
Le cache par dĂ©faut est nommĂ© “default”, donc impossibilitĂ© d’en crĂ©er de nouveaux portant ce nom.

  1. <defaultcache maxelementsinmemory=“10000″>
  2. eternal="false"
  3. timeToIdleSeconds="86400"
  4. timeToLiveSeconds="86400"
  5. overflowToDisk="true"
  6. diskSpoolBufferSizeMB="30"
  7. maxElementsOnDisk="10000000"
  8. diskPersistent="false"
  9. diskExpiryThreadIntervalSeconds="120"
  10. memoryStoreEvictionPolicy="LRU"
  11. /&gt;</defaultcache>
  • maxElementsInMemory : nombre d’élĂ©ments max en mĂ©moire, si ce nombre est dĂ©passĂ©, le moins rĂ©cemment utilisĂ© est supprimĂ©,
  • eternal : positionnĂ© Ă  true, les Ă©lĂ©ments n’expirent jamais,
  • timeToIdleSeconds : longĂ©vitĂ© d’un Ă©lĂ©ment non utilisĂ©,
  • timeToLiveSeconds : longĂ©vitĂ© d’un Ă©lĂ©ment
  • overflowToDisk : autorise l’écriture sur disque en cas de dĂ©passement de la valeur maxElementsInMemory,
  • diskSpoolBufferSizeMB : taille de la MĂ©moire tampon,
  • maxElementsOnDisk : Nombre d’élĂ©ments maximum sur le disque, si cette limite est dĂ©passĂ©e, le moins rĂ©cemment utilisĂ© est supprimĂ©,
  • diskPersistent : Si cette valeur est Ă  true, les Ă©lĂ©ments vont persister, mĂŞme après un redĂ©marrage du gestionnaire de cache,
  • diskExpiryThreadIntervalSeconds : intervalle d’expiration des threads, ne pas mettre trop bas sous peine d’utilisation intensive du ou des CPU,
  • memoryStoreEvictionPolicy : mĂ©thode de nettoyage du cache, un timestamp est mis Ă  jour lors de l’ajout ou de la lecture d’un Ă©lĂ©ment en cache
    • LRU : Least Recently Used (LRU) l’élĂ©ment le moins rĂ©cemment utilisĂ© est supprimĂ© en premier,
    • LFU Less Frequently Used : l’élĂ©ment le moins frĂ©quemment utilisĂ© est supprimĂ© en premier,
    • FIFO : first in first out : premier entrĂ©, premier sorti

Qui utilise EHCACHE :

Exemple d’utilisation avec Spring

Cet exemple présente une configuration simple pour utiliser ehcache au sein des controllers de l’application. Un tutoriel d’introduction à Spring MVC a été fait s’il vous manque les bases.

Pour la configuration, nous reprendrons celle du cache par défaut de l’exemple précédent.

Cache Manager :

Spring ira chercher la configuration dans le répertoire /WEB-INF/

  1. <bean id=“cacheManagerID” class=“org.springframework.cache.ehcache.EhCacheManagerFactoryBean”></bean>
  2.  
  3. <property name=“configLocation”> <value>/WEB-INF/ehcache.xml</value> </property>

Injection au sein du controller :Pour injecter le manager de cache dans notre controller il faudra effectuer la configuration suivante :

  1. <bean id=“indexController” class=“com.cestpasdur.controllers.IndexController”></bean>
  2. <property name=“cacheManager” ref=“cacheManagerID”> </property>

Il faudra également ajouter les accesseurs correspondants.

  1. /**
  2. * Gestionnaire de cache
  3. **/
  4. private CacheManager cacheManager ;public void setCacheManager(CacheManager cacheManager) this.cacheManager = cacheManager ;

Le cache contient une sorte de hashMap<String, Objet> d’élement identifiĂ©s par leurs clĂ©s. Ici, nous devons rĂ©cupĂ©rer un cache nommĂ© cacheName, nous devons donc faire appel Ă  la mĂ©thode getCache(”cacheName”) afin d’obtenir le cache associĂ©. Le cache par dĂ©faut s’obtiendra via la mĂŞme mĂ©thode et le paramètre “default”.

  1. <pre>Cache cache=cacheManager.getCache(“cacheName’”) ;
  2. /** Mettre instance_Objet en cache **/
  3. cache.put(new Element(“cle_du_cache”,instance_Objet)) ;
  4. /** Récupérer l’instance de l’objet précédement ajoutée **/
  5. ((Classe_Instance)cache.get(“cle_du_cache”).getObjectValue()).getItems()) ;</pre>

Avec ces quelques lignes vous pourrez crĂ©er votre premier cache, c’est cependant un exemple de base, vous pouvez y rajouter un interceptor de cache qui interceptera les appels Ă  votre DAO qui vous rendra un rĂ©sultat Ă  partir de votre cache et non de votre DAO…

Internationalisation (i18n) des sites

26 fĂ©vrier 2008 – 23:31

internationalisation
L’internationalisation (aussi connu sous l’abréviation i18n) d’une application permet de la faire fonctionner dans des contextes culturels différentes sans grande complexité. La notion i18n est beaucoup utilisé pour les portails, les applications lourdes et commence à être utilisé pour des sites personnels.

L’internationalisation des sites devient un jeu d’enfants grâce à Spring. Ici nous allons traiter un cas simple avec 2 façons de faire pour traduire rapidement, et sans trop de code, une page web.

Pour notre cas nous utilisons 2 fichiers : messages_fr.properties et messages_en.properties, respectivement les fichier en français et anglais. Voici leur contenu :

messages_fr.properties

title=Titre de mon application
heading=Locales en Francais
greeting=Bienvenu
chaine=Je suis injecté par le controller

messages_en.properties

title=Title of my application
heading=Locales in English
greeting=Welcome
chaine=I am injected by the controller

La première manière d’exploiter ces fichiers est de les paramétrer dans la classe Controller une RessourceBundle qui ira lire les données du fichier que nous souhaitons utiliser.

La variable (String) strLoc prends la valeur « fr » dans ce cas ci mais rien ne vous empêche d’utiliser la langue que vous préférez.

http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Locale.html

  1. ResourceBundle messages = ResourceBundle.getBundle(“messages”, new Locale(strLoc)) ;
  2. String test = messages.getString(“chaine”) ;

La deuxième façon, et la plus simple à mes yeux, est de mettre le paramétrage directement dans les JSP. Cela allège le code de la classe Controller et ne change quasi rien dans les JSP à part ajouter ce code en entête (ou dans un fichier include si vous avez envie).Le seul code à mettre dans le Controller est la ligne suivante :

  1. myModel.put(“resource”, strLoc) ;

ensuite le code Ă  mettre dans les JSP :

  1. <fmt value=“$model.resource”>
  2. </fmt><fmt basename=“messages”>

Maintenant si vous avez dans vos pages des balises JSTL du type suivant, celui ci sera traduit lors de la construction de la page. Avec une Locale paramétré à “fr” nous avons “Locales en Français” et avec “en” nous obtenons “Locales in English”

  1. <fmt key=“title”>

Et voilà, vous venez d’internationaliser votre site en moins de 30 minutes.