Использование сопоставленного объекта Java-to-schema в качестве модели данных Freemarker - PullRequest
0 голосов
/ 13 января 2012

Справочная информация: У меня есть веб-сервис, который раньше только получал запросы на xml, но теперь должен вернуть html для доступа через браузер. У меня есть класс Java, который сопоставлен с XML с аннотацией XmlRootElement.

Я использую Freemarker для генерации HTML на основе этого класса Java, но не могу найти способ сделать это напрямую.

В данный момент я использую NodeModel.parse для разбора xml на модель данных freemarker, но поскольку NodeModel.parse принимает файл, я сначала записываю объект Java в файл. Это, очевидно, неэффективный способ сделать это, но он выполняет свою работу.

Кто-нибудь знает способ получить модель данных freemarker из этого класса Java без предварительной записи его в файл XML?

Вот мой код:

Сопоставленный класс 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 ]

1 голос
/ 17 января 2012

Я использовал следующий код для генерации дерева узлов из аннотированного класса 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;
}
1 голос
/ 13 января 2012

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

...