web-dev-qa-db-fra.com

Suggestions pour Java modèle de courrier électronique?

nous avons une application qui doit envoyer différents types de modèles d'e-mails. Le code actuel est très lourd et peu flexible. Est-ce que quelqu'un connaît une bibliothèque pour aider avec ce type de travail ... Nous recherchons une sorte de bibliothèque de modèles pour le courrier électronique.

40
J. Scarbrough

StringTemplate est également un moteur de modèle très agréable.

23
Dave Ray

Jack Leow a déclaré qu'il avait écrit un HttpServletResponse personnalisé afin qu'il puisse réutiliser les JSP pour générer des modèles d'e-mails, je viens de faire la même chose et j'aimerais partager mon exemple de code/prototype pour ceux qui ne savent pas par où commencer:

Habituellement, lorsque vous diffusez une page JSP, vous feriez quelque chose comme ceci:

res.setContentType("text/html");
RequestDispatcher jsp = req.getRequestDispatcher("/WEB-INF/templates/" + template);
res.setStatus(200);
jsp.forward(req, res);

Maintenant, au lieu de faire cela jsp.forward à un HttpServletResponse, faites un jsp.forward à votre réponse de servlet personnalisée:

EmailServletResponse res2 = new EmailServletResponse();
jsp.forward(req, res2);
System.out.println(res2.toString()); <<-- email gets printed here

Votre réponse EmailServlet sera simplement une classe qui implémente HttpServletResponse, remplit les blancs et utilise un StringWriter sous-jacent pour effectuer la conversion toString:

public class EmailServletResponse implements HttpServletResponse {

private int status;
private StringWriter sw = new StringWriter();

@Override
public void flushBuffer() throws IOException {
    sw.flush();
}

@Override
public int getBufferSize() {
    return 1024;
}

@Override
public String getCharacterEncoding() {
    return "UTF-8";
}

@Override
public String getContentType() {
    return "text/html";
}

@Override
public Locale getLocale() {
    return Locale.getDefault();
}

@Override
public ServletOutputStream getOutputStream() throws IOException {
    return new ServletOutputStream() {
        @Override
        public void write(int b) throws IOException {
            sw.write(b);
        }
    };
}

@Override
public PrintWriter getWriter() throws IOException {
    PrintWriter pw = new PrintWriter(sw);
    return pw;
}

@Override
public boolean isCommitted() {
    return false;
}

@Override
public void reset() {       
}

@Override
public void resetBuffer() {
}

@Override
public void setBufferSize(int arg0) {
}

@Override
public void setCharacterEncoding(String arg0) {
}

@Override
public void setContentLength(int arg0) {
}

@Override
public void setContentType(String arg0) {
}

@Override
public void setLocale(Locale arg0) {
}

@Override
public void addCookie(Cookie arg0) {
}

@Override
public void addDateHeader(String arg0, long arg1) {
}

@Override
public void addHeader(String arg0, String arg1) {
}

@Override
public void addIntHeader(String arg0, int arg1) {
}

@Override
public boolean containsHeader(String arg0) {
    return false;
}

@Override
public String encodeRedirectURL(String arg0) {
    return "";
}

@Override
public String encodeRedirectUrl(String arg0) {
    return "";
}

@Override
public String encodeURL(String arg0) {
    return "";
}

@Override
public String encodeUrl(String arg0) {
    return "";
}

@Override
public void sendError(int arg0) throws IOException {

}

@Override
public void sendError(int arg0, String arg1) throws IOException {

}

@Override
public void sendRedirect(String arg0) throws IOException {

}

@Override
public void setDateHeader(String arg0, long arg1) {

}

@Override
public void setHeader(String arg0, String arg1) {


}

@Override
public void setIntHeader(String arg0, int arg1) {

}

@Override
public void setStatus(int status) {
    this.status = status;
}

@Override
public void setStatus(int status, String message) {
    setStatus(status);
}

public String toString(){
    return sw.getBuffer().toString();
}
}

N'hésitez pas à améliorer le code si nécessaire, ce fut une session de prototypage rapide :)

23

Peut-être que Apache Velocity pourrait fonctionner pour vous?

23
javamonkey79

J'ai rencontré un problème similaire il y a environ un an. Dans notre cas, nos développeurs frontaux connaissaient tous JSP, et je ne voulais vraiment pas jeter un autre moteur de template dans le mix. Je voulais quelque chose qui dépendait du processeur JSP du conteneur de servlet pour générer du contenu de courrier électronique pour moi.

C'est assez simple:

  1. Je devais avoir une page JSP dans mon application (vous pouvez la mettre dans/WEB-INF si vous ne voulez pas qu'elle soit accessible de l'extérieur).
  2. J'ai écrit un HttpServletResponse et ServletOutputStream personnalisé qui capture le contenu écrit par le conteneur de servlet et le transforme en chaîne, et je me suis appuyé sur RequestDispatcher.include(...) pour faire une "demande" au modèle JSP (j'ai également écrit un HttpServletRequest personnalisé pour isoler la requête d'origine de la mutation).
  3. Parce que c'est un peu un hack, et non la façon dont l'API servlet était destinée à être utilisée, j'ai encapsulé tout cela dans une classe utilitaire, de sorte que tout le code client doit faire est de passer dans le chemin d'accès au modèle JSP, et récupérer le contenu traité.
18
Jack Leow

Je préfère Freemarker , ici sur Velocity; imo, Freemarker beaucoup plus simple dans ce cas.

Si vous utilisez Spring, alors vous pourriez être intéressé par, Freemarker dans Spring MVC .

14
Adeel Ansari

Si vous aimez StringTemplate , vous aimerez peut-être Google Soy mieux. Meilleure convivialité, meilleure organisation, meilleure documentation et meilleur support, OMI.

3
Rich Apodaca

Il est également possible de créer un "mail content jsp" comme

mails/orderConfirmed.jsp
mails/sendingYourOrderNotification.jsp

puis faites simplement une requête du client http "/mails/*.jsp" pour obtenir le contenu du courrier que vous souhaitez.

Je pense que c'est une utilisation équitable de jsp car vous voulez quand même générer du HTML, et demander votre propre serveur ne consomme pas de bande passante.

La bonne chose est que vous pouvez faire l'inclusion jsp, ou même utiliser des bibliothèques plus avancées comme les tuiles, jsf, struts, wicket. Vous n'avez pas besoin d'apprendre un nouvel outil pour cela, vous pouvez utiliser ce que vous savez déjà. Jsps est un moteur de template assez performant, il existe depuis les années 2000.

Le mauvais point est que vous ne pouvez pas utiliser vos variables typées pour composer votre jsp, vous êtes limité aux chaînes comme paramètres de requête (ou un bon gros json :-))

C'est également un bon moyen d'isoler le code et même de fractionner les serveurs plus tard si vous avez besoin d'une optimisation des performances.

2
Zied Hamdi