背景: 我有一个以前只收到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();
}
答案 0 :(得分:1)
NodeModel
有wrap(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;
}