简体   繁体   English

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

[英]Using Java-to-schema mapped object as Freemarker data model

Background: I have a webservice that previously only received requests for xml, but now needs to return html for browser access. 背景:我有一个以前只收到xml请求的web服务,但现在需要返回html进行浏览器访问。 I have a Java class that is mapped to XML with the XmlRootElement annotation. 我有一个使用XmlRootElement注释映射到XML的Java类。

I am using Freemarker to generate HTML based on this Java class, but cannot find a way to do so directly. 我正在使用Freemarker基于此Java类生成HTML,但无法直接找到这样做的方法。

At the moment I use NodeModel.parse to parse the xml to a freemarker datamodel, but since the NodeModel.parse takes a File, I first write the Java object to a file. 目前我使用NodeModel.parse将xml解析为freemarker数据模型,但由于NodeModel.parse接受File,我首先将Java对象写入文件。 That is obviously an inefficient way to do it, but it does the job. 这显然是一种效率低下的方法,但它确实起到了作用。

Does anyone know a way to go get a freemarker datamodel out of a this Java class without first writing it to an XML file? 有没有人知道如何在不首先将其写入XML文件的情况下从这个Java类中获取freemarker数据模型?

The following is my code: 以下是我的代码:

The Java-to-Schema mapped class: 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;}    
}

Merging the data with the template: 将数据与模板合并:

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();
}

NodeModel has a wrap(org.w3c.dom.Node) method, so you surely don't have to create an XML file. NodeModel有一个wrap(org.w3c.dom.Node)方法,因此您肯定不必创建XML文件。 All you need is a tree of org.w3c.dom.Node objects, and FreeMarker doesn't care where it comes from. 您只需要一个org.w3c.dom.Node对象的树,而FreeMarker并不关心它来自何处。 Actually, if you are using the default object-wrapper of FreeMarker, you don't even need to deal with NodeModel , just drop the org.w3c.dom.Node into the data model as any other POJO, and FreeMarker will recognize it as XML. 实际上,如果你使用FreeMarker的默认对象包装器,你甚至不需要处理NodeModel ,只需将org.w3c.dom.Node放入数据模型中,就像任何其他POJO一样,FreeMarker会将其识别为XML。

Also note that FreeMarker has this ObjectWrapper abstraction. 另请注意,FreeMarker具有此ObjectWrapper抽象。 It separates the actual objects from how they are seen from the templates. 它将实际对象与从模板中看到的对象分开。 So you possibly doesn't even need to make a tree of Node -s from those objects, just make an ObjectWrapper implementation that directly understands those annotated object. 所以你甚至可能不需要从这些对象中创建一个Node -s树,只需创建一个直接理解那些带注释对象的ObjectWrapper实现。 See how DefaultObjectWrapper extends BeansWrapper , automatically wrapping Node -s, Jython object, etc. You can follow the same pattern. 了解DefaultObjectWrapper如何扩展BeansWrapper ,自动包装Node -s,Jython对象等。您可以遵循相同的模式。 But of course writing your own ObjectWrapper is extra work, especially if you need XPath support too (hint: Jaxen doesn't need Node -s). 但是编写自己的ObjectWrapper当然是额外的工作,特别是如果你也需要XPath支持(提示:Jaxen不需要Node -s)。

I have used the following code to generate a Node tree from a Java-to-Schema annotated class: 我使用以下代码从Java-Schema注释类生成节点树:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM