我可以使用Freemarker从Dropwizard View创建电子邮件吗?

时间:2016-10-24 15:05:30

标签: freemarker dropwizard

我有一个.ftl文件用于通过RESTful端点显示它的资源,我也希望通过电子邮件将此表示形式发送给用户。 Dropwizard使用Views做了一些魔术,它允许填充的模板体返回到我的REST端点(我假设为String或类似StringBuilder的爱好者。)

有没有办法在不使用其他客户端的情况下请求View的正文?我不想让我的电子邮件表示依赖于REST客户端中使用的HTML,因此没有建议将电子邮件路由到wget命中端点的内容。

通过查看dropwizard source,我似乎需要从某个地方获取ViewRenderer,可能会使用ServiceLoader.load() - 这就是ViewBundle获取的方式副本(如果你没有提供任何副本)。

1 个答案:

答案 0 :(得分:3)

正如评论中指出的那样,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";
        }

    }
}

这是我们要渲染的视图类。注意:Freemaker希望这些方法是公开的,否则它将拒绝访问它们。

相应的ftl文件:

<#-- @ftlvariable name="" type="viewTest.Two.MyView" -->
<html>
    <body>
        <h1>Hello, ${person.name?html}</h1>
    </body>
</html>

然后,在我的主要内容中,我们可以做到:

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 /服务层。在这种情况下,您可以编写一个只访问相同模型对象的客户端,以与DW通常执行的方式相同的方式实例化视图,并通过渲染简单地运行它们。

希望有所帮助,

Artur