eclipse 如何在 Java 中创建基于模板的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10055073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create Template based files in Java?
提问by N.B
I want to create a template file in java and Im using Eclipse IDE. I want to create a template file such that one program which gets the parameters from the users, it should be able to paste these parameters into the template file and then save it as a separate file. How can I do this ?
我想使用 Eclipse IDE 在 java 和 Im 中创建一个模板文件。我想创建一个模板文件,这样一个从用户那里获取参数的程序应该能够将这些参数粘贴到模板文件中,然后将其另存为一个单独的文件。我怎样才能做到这一点 ?
Please guide me.
请指导我。
Thanks N.B
谢谢注意
回答by Tom McClure
Here's how you would do this in my open-sourced template engine, Chunk.
以下是在我的开源模板引擎Chunk 中执行此操作的方法。
import com.x5.template.Theme;
import com.x5.template.Chunk;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
...
public void writeTemplatedFile() throws IOException
{
Theme theme = new Theme();
Chunk chunk = theme.makeChunk("my_template", "txt");
// replace static values below with user input
chunk.set("name", "Lancelot");
chunk.set("favorite_color", "blue");
String outfilePath = getFilePath();
File file = new File(outfilePath);
FileWriter out = new FileWriter(file);
chunk.render(out);
out.flush();
out.close();
}
my_template.txt (simply place in the classpath in themes/my_template.txt)
my_template.txt(只需放在 themes/my_template.txt 的类路径中)
My name is {$name}.
My favorite color is {$favorite_color}.
Output:
输出:
My name is Lancelot.
My favorite color is blue.
Your template can be made a bit smarter by adding |filters and :defaults to your tags.
通过在标签中添加 |filters 和 :defaults,您的模板可以变得更加智能。
my_template.txt - example 2
my_template.txt - 示例 2
My name is {$name|defang:[not provided]}.
My favorite color is {$favorite_color|defang|lc:[not provided]}.
In this example, the defang
filter removes any characters that might help form an XSS attack. The lc
filter changes the text to lowercase. And anything after the colon will be output in case the value is null.
在此示例中,defang
过滤器会删除任何可能有助于形成 XSS 攻击的字符。该lc
过滤器更改文本为小写。如果值为空,将输出冒号后的任何内容。
There is an Eclipse pluginavailable for editing Chunk templates directly in the Eclipse IDE. The plugin provides syntax highlighting and an outline view for template documents.
有一个Eclipse 插件可用于直接在 Eclipse IDE 中编辑块模板。该插件为模板文档提供语法突出显示和大纲视图。
Chunk can do a lot more, take a peek at the docsfor a quick tour. Full disclosure: I love Chunk in part because I created it.
Chunk 可以做更多事情,请查看文档以进行快速浏览。完全披露:我喜欢 Chunk 部分是因为它是我创造的。
回答by Dave Newton
回答by ilcavero
回答by cosbor11
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:
获取用户的输入参数:
但是,您这样做(向 servlet 发送请求、使用 CLI 或将参数传递给 main 方法),您将需要以某种对象或数据结构捕获输入。为此,我将创建一个简单的 pojo 类,如下所示:
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 freemarkerand mustache. Here is an example of an interface that demonstrates their common flows.
- 创建模板引擎接口:
这很方便,因此您可以尝试多个模板库。使用界面也是最佳实践,这样您就可以轻松改变主意并切换到不同的库。我最喜欢的库是freemarker和mustache。这是一个界面示例,演示了它们的常见流程。
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 freemarkertemplate...
第一个是freemarker模板的示例...
/**
* 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 mustachetemplate 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.
Freemarker 模板有一个“.ftl”扩展名,而 mustache 模板有一个“.mustache”扩展名。让我们创建一个名为“test.mustache”的小胡子模板,并将其放在“resources/templates”文件夹中。
Hello {{firstName}} {{lastName}}!
- Now, let's put our template engine to use.
- 现在,让我们使用我们的模板引擎。
It's always a good idea to create a JUnit test
创建 JUnit 测试总是一个好主意
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.
基本上就是这样。如果您使用 maven 进行设置,则测试应该在运行mvn install
目标时运行并通过。
Here is the project code that I created for this example: https://github.com/cosbor11/java-template-example
这是我为此示例创建的项目代码:https: //github.com/cosbor11/java-template-example
Hope it helps!
希望能帮助到你!