对 Java 电子邮件模板的建议?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/456148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Suggestions for Java email templating?
提问by J. Scarbrough
we have an application that needs to send out various different types of template email. The current code is very cumbersome and not very flexible. Does any one konw of a library to help with this type of work... We are looking for some kind of templating library for email.
我们有一个应用程序需要发送各种不同类型的模板电子邮件。目前的代码非常繁琐,也不是很灵活。有没有人知道可以帮助完成此类工作的库...我们正在寻找某种用于电子邮件的模板库。
采纳答案by Dave Ray
StringTemplateis also a very nice template engine.
StringTemplate也是一个非常好的模板引擎。
回答by javamonkey79
Perhaps Apache Velocitycould work for you?
也许Apache Velocity可以为您工作?
回答by Adeel Ansari
I prefer Freemarker, here over Velocity; imo, Freemarker much simpler in this case.
我更喜欢Freemarker,这里超过 Velocity ;imo,Freemarker 在这种情况下要简单得多。
If you are using Spring, then you may be interested in, Freemarker in Spring MVC.
如果您正在使用 Spring,那么您可能对Spring MVC 中的 Freemarker感兴趣。
回答by Hyman Leow
I ran into a similar problem about a year ago. In our case, our front end developers were all familiar with JSP, and I really did not want to throw another templating engine into the mix. I wanted something that relied on the servlet container's JSP processor to generate e-mail content for me.
大约一年前,我遇到了类似的问题。在我们的案例中,我们的前端开发人员都熟悉 JSP,我真的不想将另一个模板引擎混入其中。我想要一些依赖于 servlet 容器的 JSP 处理器来为我生成电子邮件内容的东西。
It's fairly straightforward:
这是相当简单的:
- I had to have a JSP page in my application (you can put it in /WEB-INF if you don't want it externally accessible).
- I wrote a custom
HttpServletResponse
andServletOutputStream
that captures content written by the servlet container and turns it into a String, and relied onRequestDispatcher.include(...)
to make a "request" to the template JSP (I also wrote a customHttpServletRequest
to isolate the original request from mutation). - Because this is a bit of a hack, and not the way the servlet API was intended to be used, I encapsulated all this in a utility class, so that all the client code has to do is pass in the path to the JSP template, and get back the processed content.
- 我的应用程序中必须有一个 JSP 页面(如果您不想从外部访问它,可以将它放在 /WEB-INF 中)。
- 我写了一个自定义
HttpServletResponse
,ServletOutputStream
它捕获由 servlet 容器编写的内容并将其转换为字符串,并依赖于RequestDispatcher.include(...)
向模板 JSP 发出“请求”(我还编写了一个自定义HttpServletRequest
来隔离原始请求与变异)。 - 因为这是一个小技巧,而不是 servlet API 的预期使用方式,所以我将所有这些都封装在一个实用程序类中,这样客户端代码所要做的就是传递到 JSP 模板的路径,并取回处理后的内容。
回答by Rich Apodaca
If you like StringTemplate, you may like Google Soybetter. Better usability, better organized, better documentation, and better supported, IMO.
如果您喜欢StringTemplate,您可能更喜欢Google Soy。更好的可用性、更好的组织、更好的文档和更好的支持,IMO。
回答by Jan Vladimir Mostert
Hyman Leow said he wrote a custom HttpServletResponse so that he could re-use JSPs for generating email templates, I just did the same and would like to share my code sample / prototype for those not sure where to begin:
Hyman Leow 说他编写了一个自定义的 HttpServletResponse 以便他可以重用 JSP 来生成电子邮件模板,我只是做了同样的事情,并希望为那些不确定从哪里开始的人分享我的代码示例/原型:
Usually when serving a JSP page, you'd do something like this:
通常在提供 JSP 页面时,您会执行以下操作:
res.setContentType("text/html");
RequestDispatcher jsp = req.getRequestDispatcher("/WEB-INF/templates/" + template);
res.setStatus(200);
jsp.forward(req, res);
Now instead of doing that jsp.forward to an HttpServletResponse, do a jsp.forward to your custom Servlet Response:
现在,不要对 HttpServletResponse 执行 jsp.forward,而是对您的自定义 Servlet 响应执行 jsp.forward:
EmailServletResponse res2 = new EmailServletResponse();
jsp.forward(req, res2);
System.out.println(res2.toString()); <<-- email gets printed here
Your EmailServlet response will simply be a class that implements HttpServletResponse, fill in the blanks and use an underlying StringWriter to accomplish the toString conversion:
您的 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();
}
}
Feel free to improve on the code where needed, this was a quick prototyping session :)
在需要的地方随意改进代码,这是一个快速的原型设计会议:)
回答by Zied Hamdi
It is also possible to create a "mail content jsp" like
也可以创建一个“邮件内容jsp”,如
mails/orderConfirmed.jsp
mails/sendingYourOrderNotification.jsp
then simply do an http client request "/mails/*.jsp" to obtain the mail content you want.
然后简单地做一个http客户端请求“/mails/*.jsp”来获取你想要的邮件内容。
I think it's a fair use of jsp since you want to generate HTML anyway, and requesting your own server is not bandwidth consuming.
我认为这是对 jsp 的合理使用,因为无论如何您都想生成 HTML,并且请求自己的服务器不会占用带宽。
The good thing is that you can do jsp inclusion, or even use more advanced libraries like tiles, jsf, struts, wicket. You don't need to learn a new tool for that, you can use what you already know. Jsps are a quite performant templating engine, they exists since the years 2000.
好消息是您可以进行 jsp 包含,甚至可以使用更高级的库,如tiles、jsf、struts、wicket。你不需要为此学习新工具,你可以使用你已经知道的东西。Jsps 是一个非常高性能的模板引擎,它们自 2000 年就存在了。
The bad point is that you can't use your typed variables to compose your jsp, you're limited to strings as request parameters (or a good huge json :-))
不好的一点是你不能使用你的类型变量来组成你的 jsp,你只能使用字符串作为请求参数(或者一个很好的巨大的 json :-))
It is also a good way to isolate code and even to split servers later if you need performance optimization.
如果您需要性能优化,这也是一种隔离代码甚至在以后拆分服务器的好方法。