How to Use freemarker in Java

Source: Internet
Author: User

In projects, XML files are usually generated and sent to another system. A simple method is to use an XML template to replace the 'mark' ($ {}) with freemarker {}), generate the final XML file.

The following is a simple example:

1. Create an XML template:

<?xml version="1.0" encoding="UTF-8"?><people  xmlns:h="http://www.w3.org/TR/html4/">    <person id="000001" age="20">        <name>            <family>${p.fname}</family>            <given>${p.gname}</given>        </name>        <email>${p.email}</email>        <link manager="${p.manager}" />         </person>    </people>

2. Replace mark with the value in Java: The following is the Java code.

package com.test.xml.freemarker;public class ValueObject {    private String fname;    private String gname;    private String email;    private String manager;    public String getFname() {        return fname;    }    public void setFname(String fname) {        this.fname = fname;    }    public String getGname() {        return gname;    }    public void setGname(String gname) {        this.gname = gname;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    public String getManager() {        return manager;    }    public void setManager(String manager) {        this.manager = manager;    }    }public class Test {    Configuration freeMarkerCfg = new Configuration();    Template template = null;    public Test() {        freeMarkerCfg.setClassForTemplateLoading(getClass(),"");        freeMarkerCfg.setObjectWrapper(new DefaultObjectWrapper());        try {            template = freeMarkerCfg.getTemplate("test.xml");        } catch (IOException e) {            // TODO            e.printStackTrace();        }    }    public void generateRequest(ValueObject obj) {        String reqFileName = "D:\\temp\\test.xml";        try {            Map<String, Object> parameters = new HashMap<String, Object>();            parameters.put("p", obj);            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName), "UTF-8");            template.process(parameters, writer);            writer.flush();        } catch (IOException e) {            e.printStackTrace();// TODO        } catch (TemplateException e) {            e.printStackTrace();// TODO        }    }    public static void main(String[] args) {        ValueObject val = new ValueObject();                val.setFname("Yao");        val.setGname("Yorker");        val.setEmail("test@mail.com");        val.setManager("manager");                new Test().generateRequest(val);    }}

The XML template and class are in package "com. Test. xml. freemarker ".

* ** In the template, the value specified by $ {Val} is used. If the Val value is null during processing, the following exception occurs:

Freemarker. Core. invalidreferenceexception: expression Valis undefined on line 46, column 63 in test. FTL

Freemarker is designed to prevent parameters written to the data model where values are transmitted, for example, parameters. put ("ABC", OBJ);, but it is written as parameters. put ("ABCD", OBJ );

But sometimes, some values do not have to have values. You can use $ {Val! ""} To bypass this exception. $ {Val! ""} Indicates that if Val is null, the value is "".

* ** Freemarker processes special characters in an XML file: <# Escape>

    <#escape x as x?xml>    <person id="000001" age="20">        <name>            <family>${p.fname}</family>            <given>${p.gname}</given>        </name>        <email>${p.email}</email>        <link manager="${p.manager}" />    </person>    </#escape>

Val. setmanager ("M & an <Ager"); the incoming values are saved to the XML file link manager = "M & amp; An & lt; Ager"/> according to XML specifications.

* ** Loop processing <# list>

    <#list people as p>    <person id="000001" age="20">        <name>            <family>${p.fname}</family>            <given>${p.gname}</given>        </name>        <email>${p.email}</email>        <link manager="${p.manager}" />    </person>    </#list>        List<ValueObject> pList = new ArrayList<ValueObject>();        ValueObject val = null;                val = new ValueObject();                val.setFname("Yao");        val.setGname("Yorker");        val.setEmail("test@mail.com");        val.setManager("m&an<ager");                pList.add(val);                val = new ValueObject();                val.setFname("J");        val.setGname("Jeremy");        val.setEmail("test1@mail.com");        val.setManager("m&an<ager");                pList.add(val);        parameters.put("people", pList);

* ** Branch processing <# If>: outputs different values to the template.

<# If P. Level = "L1">
<L1tag> XXX </l1tag>
</# If>

*** Test the generation of ultra-large files:

    public void generateRequest(List<ValueObject> pList) {        String reqFileName = "D:\\temp\\test.xml";        try {            Map<String, Object> parameters = new HashMap<String, Object>();            parameters.put("people", pList);            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName), "UTF-8");            template.process(parameters, writer);            writer.flush();        } catch (IOException e) {            e.printStackTrace();// TODO        } catch (TemplateException e) {            e.printStackTrace();// TODO        }    }    public static void testLargeVolumn(){        List<ValueObject> pList = new ArrayList<ValueObject>();        ValueObject val = null;                for(int i=0;i<400000;i++){            val = new ValueObject();                    val.setFname("Yao"+i);            val.setGname("Yorker");            val.setEmail("test@mail.com");            val.setManager("m&an<ager");            val.setLevel("L"+i);            pList.add(val);        }                new Test().generateRequest(pList);    }

One-time output. In this example, an exception occurs when the number of loops reaches 400000: Java. Lang. outofmemoryerror: Java heap Space

Solution: Output multiple times to the final output file.

1. Create a separate template from the cyclical part of the template.

First, the previous part of the output loop template is output multiple times.

The example is as follows (here, because the previous part of the loop and the subsequent part do not involve template replacement, the Java code is output directly)

The following section of the template that needs to be output cyclically:

    <#escape x as x?xml>    <#list people as p>    <person id="000001" age="20">        <name>            <family>${p.fname}</family>            <given>${p.gname}</given>        </name>        <email>${p.email}</email>        <link manager="${p.manager}" />        <#if p.level == "L1">        <l1tag>xxx</l1tag>        </#if>    </person>    </#list>    </#escape>

Java code:

public class LargeVolumnTest {    Configuration freeMarkerCfg = new Configuration();    Template template = null;    public LargeVolumnTest() {        freeMarkerCfg.setClassForTemplateLoading(getClass(),"");        freeMarkerCfg.setObjectWrapper(new DefaultObjectWrapper());        try {            template = freeMarkerCfg.getTemplate("testL.xml");        } catch (IOException e) {            // TODO            e.printStackTrace();        }    }    public void generateRequestHeader() {        String reqFileName = "D:\\temp\\test.xml";        try {            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName), "UTF-8");            writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");            writer.write("<people  xmlns:h=\"http://www.w3.org/TR/html4/\">");            writer.flush();        } catch (IOException e) {            e.printStackTrace();// TODO        }     }    public void generateRequestTail() {        String reqFileName = "D:\\temp\\test.xml";        try {            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName,true), "UTF-8");            writer.write("</people>");                        writer.flush();        } catch (IOException e) {            e.printStackTrace();// TODO        }     }        public void generateRequest(List<ValueObject> pList) {        String reqFileName = "D:\\temp\\test.xml";        try {            Map<String, Object> parameters = new HashMap<String, Object>();            parameters.put("people", pList);            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName,true), "UTF-8");            template.process(parameters, writer);            writer.flush();        } catch (IOException e) {            e.printStackTrace();// TODO        } catch (TemplateException e) {            e.printStackTrace();// TODO        }    }    public  void testLargeVolumn(){        generateRequestHeader();        List<ValueObject> pList = new ArrayList<ValueObject>();        ValueObject val = null;        int i=0;        for(;i<500000;i++){            val = new ValueObject();                    val.setFname("Yao"+i);            val.setGname("Yorker");            val.setEmail("test@mail.com");            val.setManager("m&an<ager");            val.setLevel("L"+i);            pList.add(val);            if(i%10000==0){                generateRequest(pList);                pList.clear();            }        }        if(i%10000!=0){            generateRequest(pList);        }        generateRequestTail();    }    public static void main(String[] args) {                new LargeVolumnTest().testLargeVolumn();    }}

Note that the part at the end of the output loop is appended to the file: outputstreamwriter writer = new outputstreamwriter (New fileoutputstream (reqfilename, true), "UTF-8 ");

The final generated XML document is 90 MB, and no exception is reported.

Here we have freemarker Chinese manual: http://download.csdn.net/user/kkdelta

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.