使用自定义freemarker模板

时间:2018-02-18 15:16:05

标签: freemarker

我想知道是否有人可以帮助我使用Apache FreeMarker?我正在尝试使用自定义模型,但我无法理解。

想象一下,我想要转储查询的结果(在FreeMarker模板中使用java ResultSet)。什么是最好的方法?

我在Google上找到了这个类:ResultSetTemplateModel

import java.sql.ResultSet;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;


public class ResultSetTemplateModel implements TemplateSequenceModel {

    private ResultSet rs = null;
    public ResultSetTemplateModel(ResultSet rs) {
        this.rs = rs;
    }
    public TemplateModel get(int i) throws TemplateModelException {
        try {
            rs.next();
        } catch(Exception e) {
            throw new TemplateModelException(e.toString());
        }
        TemplateModel model = new Row(rs);
        return model;
    }

    public int size() throws TemplateModelException {
        int size=0;
        try {
            rs.last();
            size = rs.getRow();
            rs.beforeFirst();
        } catch (Exception e ) {
            throw new TemplateModelException( e.toString());
        }
        return size;
    }


    class Row implements TemplateHashModel {

        private ResultSet rs = null;
        public Row(ResultSet rs) {
            this.rs = rs;
        }

        public TemplateModel get(String s) throws TemplateModelException {
            TemplateModel model = null;
            try {
                model = new SimpleScalar( rs.getString(s) );
            } catch (Exception e) { e.printStackTrace(); }
            return model;
        }

        public boolean isEmpty() throws TemplateModelException {
            boolean isEmpty = false;
            if ( rs == null ) { isEmpty = true; }
            return isEmpty;
        }

    }
}

我有一个非常简单的课程(我甚至比以前更容易):

public static void main(String[] args) {

    try {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setClassForTemplateLoading(MyCLASS.class, "/");
        StringWriter out = new StringWriter();
        Map<String, Object> parameters = new TreeMap<>();

        ResultSet rs = getResultSet("Select foo, bar FROM my_table");
        parameters.put("hello", "World");
        parameters.put("result", rs);


        Template temp = cfg.getTemplate("template.txt");
        temp.process(parameters, out);

        System.out.println("out = " + out);
    } catch (IOException | TemplateException e) {
        e.printStackTrace();
    }

}

我的模板

Hello ${hello}
<#-- how do I specify ResultSet columns here ?? -->

我如何使用自定义模板?任何建议?我知道如何加载模板文件。但我不知道如何指定它是模板中的自定义模型。

感谢你们的支持:)

1 个答案:

答案 0 :(得分:0)

有两种方法可以使用ResultSetTemplateModel来包装ResultSet - s:

  • 通过覆盖DefaultObjectWrapper延长handleUnknownType,如果new ResultSetTemplateModel((ResultSet) obj)obj,则返回ResultSet,否则请super 。然后使用Configuration.setObjectWrapper实际使用它。

  • 或者,将new ResultSetTemplate(rs)添加到parameters而不是rs;如果某些内容已经是TempalteModel,则不会再次换行。请注意,如果您从模板中的其他位置获得ResultSet,则此方法无法正常工作,因为它会避免您的手动换行,因此通常会扩展DefaultObjectWrapper

请注意,显示的ResultSetTemplateModel实现非常有限。 ObjectWrapper也应该传递给构造函数,并存储在final字段中。然后,代替new SimpleScalar( rs.getString(s) )它应该objectWrapper.wrap(rs.getObject(s))