使用 Java 到架构的映射对象作为 Freemarker 数据模型

发布于 2024-12-26 23:25:20 字数 1378 浏览 4 评论 0原文

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

我正在使用 Freemarker 基于这个 Java 类生成 HTML,但找不到直接执行此操作的方法。

目前,我使用 NodeModel.parse 将 xml 解析为 freemarker 数据模型,但由于 NodeModel.parse 需要一个文件,所以我首先将 Java 对象写入文件。这显然是一种低效的方法,但它确实有效。

有谁知道如何从 Java 类中获取 freemarker 数据模型,而无需先将其写入 XML 文件吗?

以下是我的代码:

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

Background:
I have a webservice that previously only received requests for xml, but now needs to return html for browser access.
I have a Java class that is mapped to XML with the XmlRootElement annotation.

I am using Freemarker to generate HTML based on this Java class, but cannot find a way to do so directly.

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. 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?

The following is my code:

The Java-to-Schema mapped class:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

星光不落少年眉 2025-01-02 23:25:20

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

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

NodeModel has a wrap(org.w3c.dom.Node) method, so you surely don't have to create an XML file. All you need is a tree of org.w3c.dom.Node objects, and FreeMarker doesn't care where it comes from. 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.

Also note that FreeMarker has this ObjectWrapper abstraction. 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. See how DefaultObjectWrapper extends BeansWrapper, automatically wrapping Node-s, Jython object, etc. You can follow the same pattern. But of course writing your own ObjectWrapper is extra work, especially if you need XPath support too (hint: Jaxen doesn't need Node-s).

[旋木] 2025-01-02 23:25:20

我使用以下代码从 Java-to-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;
}

I have used the following code to generate a Node tree from a Java-to-Schema annotated class:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文