Java电子邮件模板的建议? [关闭]

Posted

技术标签:

【中文标题】Java电子邮件模板的建议? [关闭]【英文标题】:Suggestions for Java email templating? [closed] 【发布时间】:2010-10-02 03:39:23 【问题描述】:

我们有一个应用程序需要发送各种不同类型的模板电子邮件。当前的代码非常繁琐,也不是很灵活。有没有人知道图书馆可以帮助完成这类工作...我们正在寻找某种用于电子邮件的模板库。

【问题讨论】:

【参考方案1】:

也许Apache Velocity 对你有用?

【讨论】:

+1 我以前就用过 Velocity + Spring。 我也是。 (速度,不是弹簧)【参考方案2】:

StringTemplate 也是一个非常不错的模板引擎。

【讨论】:

好电话。作为旁注,您可能希望在将主题/正文内容传递到 JavaMail 之类的 API 之前进行替换。否则,由于编码或换行问题,您最终可能会生成无效的 EML 文件。 我们最终使用了 StringTemplate。对于我们的情况非常简单但灵活。 但是,哦!它有一个多么可怕的网站。反馈表已损坏。它也不在 Maven 中。 Java 文化中的什么东西说可以把东西放在一起,让它们看起来很糟糕,并期望人们“使用”它们?将 Django(基于 python 的项目)文档与任何 java 产品之一进行比较。我非常失望。我将使用 Velocity——尽管它有副作用、臃肿而且可能更糟。 如果需要通过maven导入可以在这里找到:mvnrepository.com/artifact/org.antlr/ST4 如果你喜欢 StringTemplate,你可能更喜欢 Google Soy Templates:developers.google.com/closure/templates 还有,drozzy 说的。【参考方案3】:

比起 Velocity,我更喜欢 Freemarker; imo,Freemarker 在这种情况下要简单得多。

如果您使用的是 Spring,那么您可能会感兴趣,Freemarker in Spring MVC。

【讨论】:

+1 表示 Freemarker 在允许的范围内比 Velocity 更严格。【参考方案4】:

大约一年前我遇到了类似的问题。在我们的例子中,我们的前端开发人员都熟悉 JSP,我真的不想在混合中加入另一个模板引擎。我想要依靠 servlet 容器的 JSP 处理器为我生成电子邮件内容的东西。

这很简单:

    我的应用程序中必须有一个 JSP 页面(如果您不希望从外部访问它,可以将它放在 /WEB-INF 中)。 我写了一个自定义的HttpServletResponseServletOutputStream,它捕获servlet容器写入的内容并将其转换为String,并依靠RequestDispatcher.include(...)向模板JSP发出“请求”(我还写了一个自定义 HttpServletRequest 以将原始请求与突变隔离开来)。 因为这有点小技巧,而不是 servlet API 的预期使用方式,所以我将所有这些都封装在一个实用程序类中,这样客户端代码所要做的就是将路径传递给JSP模板,并取回处理后的内容。

【讨论】:

你是从一个例子开始的吗?我非常喜欢使用 JSP 模板的想法。 不,这是我在上一份工作中想到的。不幸的是,我无法再访问代码了。 在这里查看我的代码示例,它实际上相当简单:***.com/a/20847683/527533 如果您不想将 jars 添加到项目中,这将非常有用:这是我的情况,因为我在 GAE 上,并且每个添加的 jar 都会增加实例启动的权重。所以谢谢你的提示,我不是自己来的:)【参考方案5】:

如果你喜欢StringTemplate,你可能会更喜欢Google Soy。更好的可用性、更好的组织、更好的文档和更好的支持,IMO。

【讨论】:

【参考方案6】:

有一个example 可以使用 Snippetory 处理电子邮件。

【讨论】:

【参考方案7】:

Jack Leow 说他编写了一个自定义 HttpServletResponse,以便他可以重用 JSP 来生成电子邮件模板,我只是做了同样的事情,并想与那些不确定从哪里开始的人分享我的代码示例/原型:

通常在提供 JSP 页面时,您会执行以下操作:

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

现在不要对 HttpServletResponse 执行 jsp.forward,而是对您的自定义 Servlet 响应执行 jsp.forward:

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

您的 EmailServlet 响应将只是一个实现 HttpServletResponse 的类,填空并使用底层 StringWriter 来完成 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();


在需要的地方随意改进代码,这是一个快速的原型制作会议:)

【讨论】:

PS,不如用HttpServletResponseWrapper【参考方案8】:

也可以像这样创建“邮件内容jsp”

mails/orderConfirmed.jsp
mails/sendingYourOrderNotification.jsp

然后简单地做一个http客户端请求“/mails/*.jsp”来获取你想要的邮件内容。

我认为这是对 jsp 的合理使用,因为无论如何您都想生成 HTML,并且请求您自己的服务器不会消耗带宽。

好处是你可以做jsp包含,甚至使用更高级的库,比如tiles、jsf、struts、wicket。你不需要为此学习新工具,你可以使用你已经知道的东西。 Jsps 是一个非常高效的模板引擎,它们从 2000 年就存在了。

不好的一点是你不能使用你的类型变量来组成你的 jsp,你被限制为字符串作为请求参数(或者一个很好的巨大的 json :-))

如果您需要性能优化,这也是隔离代码甚至拆分服务器的好方法。

【讨论】:

如果您在jsps前面带有控制器或servlet,那么您可以使用请求参数来加载完整的对象以供在JSP中使用 是的,但如果您打算稍后将邮件服务器与应用程序的其余部分分开,我建议避免这种情况(尤其是现在我们总是有个性化的邮件:因为您必须插入取消订阅链接客户ID,你叫这个人的名字,等等。所以可能有与邮件活动一样多的jsp处理(至少数千个)。在同一个“主”服务器上完成该任务可能会降低前端性能【参考方案9】:

这是Java template benchmark

【讨论】:

以上是关于Java电子邮件模板的建议? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的“电子邮件地址”内容类型的文本字段不建议电子邮件? [关闭]

.NET 组件访问电子邮件收件箱的建议 [关闭]

位置和边距顶部负值不适用于 html 电子邮件模板 [关闭]

springboot系列(十五):如何实现静态邮件模板发送?你一定得会|超级详细,建议收藏

Openerp 电子邮件模板位置

通过 Java 发送电子邮件模板时的 Mandrill-Error code-5