Let's break this into steps:
Get the input parameters from the user:
However you do this (sending a request to a servlet, using a CLI, or passing arguments to the main method) you will need to capture the input in some sort of object or data structure. To do this I would create a simple pojo class like this:
public class UserInput
{
protected String firstName;
protected String lastName;
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
}
- Create a TemplateEngine Interface:
This is handy so you can try out several template libraries. It is also best practice to use an interface so you can easily change your mind and switch to a different library. My favorite libraries are freemarker and mustache. Here is an example of an interface that demonstrates their common flows.
public interface ITemplateEngine
{
/**
* creates the template engines instance and sets the root path to the templates in the resources folder
* @param templatesResouceFolder
*/
public void init(String templatesResouceFolder);
/**
* sets the current template to use in the process method
* @param template
*/
public void setTemplate(String template);
/**
* compiles and writes the template output to a writer
* @param writer
* @param data
*/
public void process(Writer writer, Object data);
/**
* returns the template file extension
* @return
*/
public String getTemplateExtension();
/**
* finishes the write process and closes the write buffer
*/
public void flush();
}
- Implement the Interface
The first is an example of a freemarker template...
/**
* This class is a freemarker implementation of ITemplateEngine
* Use ${obj.prop} in your template to replace a certain the token
* Use ${obj.prop!} to replace with empty string if obj.prop is null or undefined
*
*
*/
public class FreemarkerTemplateEngine implements ITemplateEngine
{
protected Configuration instance = null;
protected String templatesFolder = "templates";
protected Template templateCompiler = null;
protected Writer writer = null;
@Override
public void init(String templatesResouceFolder)
{
if(instance == null){
instance = new Configuration();
instance.setClassForTemplateLoading(this.getClass(), "/");
this.templatesFolder = templatesResouceFolder;
}
}
@Override
public void setTemplate(String template)
{
try
{
templateCompiler = instance.getTemplate(templatesFolder + File.separatorChar + template + getTemplateExtension());
} catch (IOException ex)
{
Logger.getLogger(FreemarkerTemplateEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void process(Writer writer, Object data)
{
try
{
templateCompiler.process(data, writer);
this.writer = writer;
} catch (TemplateException | IOException ex)
{
Logger.getLogger(FreemarkerTemplateEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public String getTemplateExtension()
{
return ".ftl";
}
@Override
public void flush()
{
try
{
this.writer.flush();
} catch (IOException ex)
{
Logger.getLogger(FreemarkerTemplateEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And this is an example of a mustache template engine...
/**
*
* Use {{obj.prop}} in your template to replace a certain the token
* If obj.prop is null or undefined, it will automatically replace it with an empty string
* If you want to exclude an entire section based on if a value is null, undefined, or false you can do this:
* {{#obj.prop}}
* Never shown
* {{/obj.prop}}
*/
public class MustacheTemplateEngine implements ITemplateEngine
{
protected MustacheFactory factory = null;
protected Mustache instance = null;
protected Writer writer = null;
protected String templatesFolder = "templates";
@Override
public void init(String templatesResouceFolder)
{
if(factory == null){
factory = new DefaultMustacheFactory();
this.templatesFolder = templatesResouceFolder;
}
}
@Override
public void setTemplate(String template)
{
instance = factory.compile(templatesFolder + File.separatorChar + template + getTemplateExtension());
}
@Override
public void process(Writer writer, Object data)
{
this.writer = instance.execute(writer, data);
}
@Override
public String getTemplateExtension()
{
return ".mustache";
}
@Override
public void flush()
{
try
{
this.writer.flush();
} catch (IOException ex)
{
Logger.getLogger(MustacheTemplateEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
- Create the template
Freemarker templates have a '.ftl' extension and mustache templates have a '.mustache' extension. Let's just create a mustache template called 'test.mustache', and put it in the 'resources/templates' folder.
Hello {{firstName}} {{lastName}}!
- Now, let's put our template engine to use.
It's always a good idea to create a JUnit test
public class JavaTemplateTest
{
ITemplateEngine templateEngine = new MustacheTemplateEngine();
public File outputFolder = new File(System.getProperty("user.home") + "/JavaTemplateTest");
@Before
public void setUp()
{
outputFolder.mkdirs();
}
@After
public void tearDown()
{
for (File file : outputFolder.listFiles())
{
file.delete();
}
outputFolder.delete();
}
public JavaTemplateTest()
{
}
@Test
public void testTemplateEngine() throws Exception
{
//mock the user input
UserInput userInput = new UserInput();
userInput.setFirstName("Chris");
userInput.setLastName("Osborn");
//create the out put file
File file = new File(outputFolder.getCanonicalPath() + File.separatorChar + "test.txt");
//create a FileWriter
try (Writer fileWriter = new FileWriter(file.getPath()))
{
//put the templateEngine to work
templateEngine.init("templates");
templateEngine.setTemplate("test"); //resources/templates/test.mustache
templateEngine.process(fileWriter, userInput); //compile template
templateEngine.flush(); //write to file
}
//Read from the file and assert
BufferedReader buffer = new BufferedReader(new FileReader(file));
Assert.assertEquals("Hello Chris Osborn!", buffer.readLine());
}
}
That's basically it. If you set this up using maven, the test should run and pass when running the mvn install
goal.
Here is the project code that I created for this example: https://github.com/cosbor11/java-template-example
Hope it helps!