我可以使用 Freemarker 从 Dropwizard View 创建电子邮件吗?
Can I create an email from a Dropwizard View using Freemarker?
我有一个资源的 .ftl
文件,用于通过 RESTful 端点显示它,我还想通过电子邮件将此表示发送给用户。 Dropwizard 用 Views 做了一些魔法,允许填充的模板正文返回到我的 REST 端点(我假设是 String
或像 StringBuilder
这样的更高级的东西)。
有没有办法在不使用其余客户端的情况下请求 View
的正文?我不想让我的电子邮件表示依赖于 REST 客户端中使用的 HTML
,因此没有建议将电子邮件路由到 wget
命中端点的内容。
从 dropwizard source 来看,我似乎需要从某个地方获取 ViewRenderer
,可能是使用 ServiceLoader.load()
- 因为这就是 ViewBundle
获取副本(如果您不提供任何副本)。
正如评论中所指出的,Rossiar 是完全正确的。
实现此目的的方法是使用与 DW 相同的 ViewRenderer
。不必使用 ServiceLocator 模式,因为它们所做的只是调用构造函数。
一个小例子:
public class MyView extends View {
private TestPerson person;
protected MyView(TestPerson person) {
super("TestView.ftl");
this.person = person;
}
public TestPerson getPerson() {
return person;
}
public static class TestPerson {
public String getName() {
return "PandaaDb";
}
}
}
这是我们要呈现的视图 class。注意:Freemaker 期望这些方法是 public,否则它将拒绝访问它们。
对应的ftl文件:
<#-- @ftlvariable name="" type="viewTest.Two.MyView" -->
<html>
<body>
<h1>Hello, ${person.name?html}</h1>
</body>
</html>
然后,在 my main 中,我们可以做:
public class ViewTestMain {
public static void main(String[] args) throws UnsupportedEncodingException {
FreemarkerViewRenderer render = new FreemarkerViewRenderer();
TestPerson p = new TestPerson();
MyView v = new MyView(p);
ByteArrayOutputStream st = new ByteArrayOutputStream();
try {
render.render(v, Locale.getDefault(), st);
} catch (IOException e) {
e.printStackTrace();
}
String string = st.toString("UTF-8");
System.out.println(string);
}
}
或者,或者,我们可以通过查询服务定位器并检查每个 ViewRenderer(如果适用)来重用 DW 为我们布局的模式。
public class ViewTestMain {
public static void main(String[] args) throws UnsupportedEncodingException {
ServiceLoader<ViewRenderer> load = ServiceLoader.load(ViewRenderer.class);
TestPerson p = new TestPerson();
MyView v = new MyView(p);
ByteArrayOutputStream st = new ByteArrayOutputStream();
ViewRenderer r = null;
for(ViewRenderer vr : load) {
if(vr.isRenderable(v)) {
r = vr;
}
}
try {
r.render(v, Locale.getDefault(), st);
} catch (IOException e) {
e.printStackTrace();
}
String string = st.toString("UTF-8");
System.out.println(string);
}
}
请注意,您可以通过简单地将实现添加到服务来添加自己的 ServiceRenderer。这是通过将具有 ServiceRender 接口名称(完全限定)的文件放入
来完成的
src/main/resources/META-INF/services
然后将完全限定的实现名称添加到该文件中。这将使它被发现。
将打印:
<html>
<body>
<h1>Hello, PandaaDb</h1>
</body>
</html>
现在,我假设您已将 DAO/Service 层从球衣层中分离出来。在这种情况下,您可以编写一个客户端来简单地访问相同的模型对象,以 DW 通常执行的相同方式实例化视图,并通过渲染简单地 运行 它们。
希望对您有所帮助,
阿图尔
我有一个资源的 .ftl
文件,用于通过 RESTful 端点显示它,我还想通过电子邮件将此表示发送给用户。 Dropwizard 用 Views 做了一些魔法,允许填充的模板正文返回到我的 REST 端点(我假设是 String
或像 StringBuilder
这样的更高级的东西)。
有没有办法在不使用其余客户端的情况下请求 View
的正文?我不想让我的电子邮件表示依赖于 REST 客户端中使用的 HTML
,因此没有建议将电子邮件路由到 wget
命中端点的内容。
从 dropwizard source 来看,我似乎需要从某个地方获取 ViewRenderer
,可能是使用 ServiceLoader.load()
- 因为这就是 ViewBundle
获取副本(如果您不提供任何副本)。
正如评论中所指出的,Rossiar 是完全正确的。
实现此目的的方法是使用与 DW 相同的 ViewRenderer
。不必使用 ServiceLocator 模式,因为它们所做的只是调用构造函数。
一个小例子:
public class MyView extends View {
private TestPerson person;
protected MyView(TestPerson person) {
super("TestView.ftl");
this.person = person;
}
public TestPerson getPerson() {
return person;
}
public static class TestPerson {
public String getName() {
return "PandaaDb";
}
}
}
这是我们要呈现的视图 class。注意:Freemaker 期望这些方法是 public,否则它将拒绝访问它们。
对应的ftl文件:
<#-- @ftlvariable name="" type="viewTest.Two.MyView" -->
<html>
<body>
<h1>Hello, ${person.name?html}</h1>
</body>
</html>
然后,在 my main 中,我们可以做:
public class ViewTestMain {
public static void main(String[] args) throws UnsupportedEncodingException {
FreemarkerViewRenderer render = new FreemarkerViewRenderer();
TestPerson p = new TestPerson();
MyView v = new MyView(p);
ByteArrayOutputStream st = new ByteArrayOutputStream();
try {
render.render(v, Locale.getDefault(), st);
} catch (IOException e) {
e.printStackTrace();
}
String string = st.toString("UTF-8");
System.out.println(string);
}
}
或者,或者,我们可以通过查询服务定位器并检查每个 ViewRenderer(如果适用)来重用 DW 为我们布局的模式。
public class ViewTestMain {
public static void main(String[] args) throws UnsupportedEncodingException {
ServiceLoader<ViewRenderer> load = ServiceLoader.load(ViewRenderer.class);
TestPerson p = new TestPerson();
MyView v = new MyView(p);
ByteArrayOutputStream st = new ByteArrayOutputStream();
ViewRenderer r = null;
for(ViewRenderer vr : load) {
if(vr.isRenderable(v)) {
r = vr;
}
}
try {
r.render(v, Locale.getDefault(), st);
} catch (IOException e) {
e.printStackTrace();
}
String string = st.toString("UTF-8");
System.out.println(string);
}
}
请注意,您可以通过简单地将实现添加到服务来添加自己的 ServiceRenderer。这是通过将具有 ServiceRender 接口名称(完全限定)的文件放入
来完成的src/main/resources/META-INF/services
然后将完全限定的实现名称添加到该文件中。这将使它被发现。
将打印:
<html>
<body>
<h1>Hello, PandaaDb</h1>
</body>
</html>
现在,我假设您已将 DAO/Service 层从球衣层中分离出来。在这种情况下,您可以编写一个客户端来简单地访问相同的模型对象,以 DW 通常执行的相同方式实例化视图,并通过渲染简单地 运行 它们。
希望对您有所帮助,
阿图尔