Envoyer des mails en Spring

Gérer l'envoi des messages mail avec Velocity et Spring

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

Les mails, malgré la montée en puissance de la communication instantanée via les réseaux sociaux, restent un outil indisocciable des applications web. En mars 2013, Galen Gruman a publié un article expliquant pourquoi les applications sociales ne remplaceront jamais un e-mail.

C'est d'ailleurs une des raisons pour lesquelles on va aborder l'aspect d'envoi des e-mails dans Spring dans un article séparé. On début on verra quels sont les moyens de gestion de la communication mail dans ce framework. Ensuite on présentera l'implémentation de l'un de ces moyens avec l'exemple de l'envoi d'un mail suite à l'ouverture du compte.

Envoyer des mails dans Spring

Un package entier, org.springframework.mail, est consacré à l'envoi des mails grâce au Spring. L'interface principale utilisée pour l'envoi des mails est MailSender. Elle permet de construire un système d'expédition complexe grâce à la gestion à des niveaux différents. Les exceptions lancées concernent aussi bien les erreurs de traitement des messages que celles liées à l'authentification.

L'implémentation de cette interface qu'on utilisera dans notre application, org.springframework.mail.javamail.JavaMailSenderImpl, supporte les deux classes gérant types MIME des e-mails (MimeMessage du JavaMail et SimpleMailMessage du Spring).

La configuration du bean qui s'appelle mainSender se fait dans un fichier de contexte, comme suit :

    <beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
	    <beans:property name="host" value="smtp.gmail.com" />
	    <beans:property name="port" value="587" />
	    <beans:property name="username" value="bartkonieczny@gmail.com" />
	    <beans:property name="password" value="********" />
 
    	<beans:property name="javaMailProperties">
	        <beans:props>
       	        <beans:prop key="mail.smtp.auth">true</beans:prop>
       	        <beans:prop key="mail.smtp.starttls.enable">true</beans:prop>
       	    </beans:props>
	    </beans:property>
    </beans:bean>

On ne remarque rien de mystérieux dans cette configuration. Juste les données d'accès et la configuration des propriétés liées à l'authentification demandée par Gmail y sont présentes. Cependant, ce n'est pas le bean qui nous servira à expédier les mails réellement. Il s'agit juste d'une configuration qu'on va injecter dans un autre bean qui se chargera de cette tâche.

Envoyer les mails avec Spring et Velocity

L'outil qu'on emploiera pour expédier les mails, va se baser sur Velocity. Il est un système des templates qui permet de gérer facilement la transmissions des variables vers la partie des vues. En plus, dans les templates Velocity on peut utiliser les variables selon la manière très simple, en les précédant par le signe du dollar ($). Regardons donc comment le bean avec notre outil de mail est configuré :

    <beans:bean id="mailerTool" name="mailerTool" class="library.tools.MailerTool">
	    <beans:property name="mailSender" ref="mailSender" />
        <beans:property name="velocityEngine" ref="velocityEngine"/>
	    <beans:property name="sender" value="bartkonieczny@gmail.com" />
	    <beans:property name="localeResolver" ref="localeResolver" />
    </beans:bean>

Le mailerTool possède 4 propriétés :
- mailerSender : le bean défini dans le paragraphe précédent
- velocityEngine : le moteur du Velocity utilisé pour générer les messages des mails
- sender : une chaîne de caractères avec le mail de l'expéditeur des mails
- localeResolver : le bean qui nous permettra de définir la langue de l'utilisateur, donc de lui fournir le message compréhensible

Notre mailerTool va se baser sur les traductions placées dans les fichiers de configuration qui contiendra les relations entre les codes et les templates à utiliser. Comme le démontre cet exemple :

; register template
body_register_fr = register_fr.vtl
body_register_en = register_en.vtl
body_register_pl = register_pl.vtl

title_register_fr = ${vars.login}, vous venez de vous enregistrer
title_register_en = ${vars.login}, you must validate your subscription
title_register_pl = ${vars.login}, czekamy tylko na Twoja aktywację konta

En occurrence, on récupérera le titre du message d'enregistrement à travers le code "title_registrer_LANG" où LANG signifie le code ISO de la langue de l'utilisateur. Le contenu du mail à envoyer va se faire via la récupération du fichier spécifié sous "body_register_LANG".

Le code du mailerTool qui préparera et enverrai des mails, se présente ainsi :

afficher le code

Dans le code ci-dessus, à la première étape on charge les propriétés. Ensuite on récupère l'instance implémentant l'interface HttpServletRequest. Elle sera utilisée pour déterminer la langue du message à envoyer. Plus loin on détermine les fichiers de contenu qui vont être gérés par MimeMessagePreparator. Après la préparation du contenu par les méthodes prepareTitle() et prepareTemplate(), on expédie le mail au destinataire.

Voici l'implémentation du mailerTool dans le code du service chargé de gérer les actions d'un utilisateur enregistré :

afficher le code

L'implémentation est plutôt banale. Tout d'abord on définit les données qui vont être transmises au mailerTool. Ensuite on effectue la transmission grâce au setMailData() et setVars(). Ensuite on effectue l'envoi du mail en appelant la méthode send() décrite précédemment.

Bartosz KONIECZNY Mails

Une question ? Une remarque ?

*

*

Un conseil Symfony2

Comment valider les checkboxes avec Symfony2 ?

La validation des checkboxes sous Symfony2 se déroule avec une contrainte appelée ChoiceConstraint.

Voici l'exemple de l'utilisation:

$metadata->addPropertyConstraint('orderPreferedGift', new Choice(array('choices' => Gifts::getGiftTypes(true), 'multiple' => true, 'min' => 1,  'multipleMessage' => "Veuillez choisir au moins un type de cadeau", 'groups' => array('validationGroup'))));


Cette contrainte est très puissante. On peut déterminer par exemple la quantité des champs minimale ou maximale à cocher par utilisateur. Il est également possible de vérifier le types des valeurs.