使用Java-to-schema映射对象作为Freemarker数据模型

时间:2012-01-13 12:34:23

标签: java xml annotations freemarker

背景: 我有一个以前只收到xml请求的web服务,但现在需要返回html进行浏览器访问。 我有一个使用XmlRootElement注释映射到XML的Java类。

我正在使用Freemarker基于此Java类生成HTML,但无法直接找到这样做的方法。

目前我使用NodeModel.parse将xml解析为freemarker数据模型,但由于NodeModel.parse接受File,我首先将Java对象写入文件。这显然是一种效率低下的方法,但它确实起到了作用。

有没有人知道如何在不首先将其写入XML文件的情况下从此Java类中获取freemarker数据模型?

以下是我的代码:

Java-to-Schema映射类:

@XmlRootElement(name = "report")
public class Report {
    private String id;  
    private String time;    

    public Report() {}

    public String getTime() {return time;}
    public void setTime(String time) {this.time = time;}

    public String getId() {return this.id;}    
    public void setId(String id) {this.id = id;}    
}

将数据与模板合并:

public String getReportsAsHtml(@QueryParam("lastUpdate") String lastUpdate){
    MySQLAccess dao = new MySQLAccess();
    List<Report> reports = dao.readReports(lastUpdate);
Template  temp = TemplateConfiguration.getInstance().getTemplateConfiguration().getTemplate("list_template.ftl");
    **HashMap<String, NodeModel> root = new HashMap<String, NodeModel>();**
    **root.put("doc", NodeModel.parse(Java2XML.getXMLFromJava(reports)));**
    StringWriter output = new StringWriter();
    temp.process(root, output);
    output.flush();
    return output.toString();
}

2 个答案:

答案 0 :(得分:1)

NodeModelwrap(org.w3c.dom.Node)方法,因此您无需创建XML文件。您所需要的只是org.w3c.dom.Node个对象的树,而FreeMarker并不关心它来自何处。实际上,如果您使用FreeMarker的默认对象包装器,您甚至不需要处理NodeModel,只需将org.w3c.dom.Node放入数据模型中,就像任何其他POJO一样,FreeMarker将识别它是XML。

另请注意,FreeMarker具有此ObjectWrapper抽象。它将实际对象与从模板中看到的对象分开。因此,您甚至可能不需要从这些对象中创建Node - s树,只需创建一个直接理解这些带注释对象的ObjectWrapper实现。了解DefaultObjectWrapper如何扩展BeansWrapper,自动包装Node - s,Jython对象等。您可以遵循相同的模式。但是编写自己的ObjectWrapper当然是额外的工作,特别是如果你也需要XPath支持(提示:Jaxen不需要Node - s)。

答案 1 :(得分:1)

我使用以下代码从Java-to-Schema注释类生成Node树:

public static Node getNodeFromReport(Object report){
    JAXBContext context = JAXBContext.newInstance(report.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
    Document result = docFac.newDocumentBuilder().newDocument();

    marshaller.marshal(report, result);

    return result;
}