Java でテンプレート ファイルを作成し、Eclipse IDE を使用しています。ユーザーからパラメーターを取得する 1 つのプログラムが、これらのパラメーターをテンプレート ファイルに貼り付けて、別のファイルとして保存できるように、テンプレート ファイルを作成したいと考えています。これどうやってするの ?
私を案内してください。
ありがとうNB
オープンソースのテンプレート エンジン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 (themes/my_template.txt のクラスパスに配置するだけです)
My name is {$name}.
My favorite color is {$favorite_color}.
出力:
My name is Lancelot.
My favorite color is blue.
|filters と :defaults をタグに追加することで、テンプレートを少し賢くすることができます。
my_template.txt - 例 2
My name is {$name|defang:[not provided]}.
My favorite color is {$favorite_color|defang|lc:[not provided]}.
この例では、defang
フィルターは、XSS 攻撃の形成に役立つ可能性のある文字をすべて削除します。lc
フィルターはテキストを小文字に変更します。値が null の場合は、コロンの後のものが出力されます。
Eclipse IDE で Chunk テンプレートを直接編集できるEclipse プラグインがあります。このプラグインは、テンプレート ドキュメントの構文の強調表示とアウトライン ビューを提供します。
Chunk はさらに多くのことができます。クイック ツアーについてはドキュメントを参照してください。完全な開示: 私が Chunk を気に入っているのは、それを作成したからでもあります。
これをいくつかのステップに分けてみましょう:
ユーザーから入力パラメーターを取得します。
ただし、これを行う (サーブレットにリクエストを送信する、CLI を使用する、メイン メソッドに引数を渡す) 場合は、何らかのオブジェクトまたはデータ構造で入力をキャプチャする必要があります。これを行うには、次のような単純な 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;
}
}
これは便利なので、いくつかのテンプレート ライブラリを試すことができます。また、気が変わって別のライブラリに簡単に切り替えられるように、インターフェイスを使用することもベスト プラクティスです。私のお気に入りのライブラリは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();
}
1 つ目は、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);
}
}
}
これは口ひげテンプレート エンジンの例です...
/**
*
* 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);
}
}
}
Freemarker テンプレートには「.ftl」拡張子があり、mustache テンプレートには「.mustache」拡張子があります。「test.mustache」という口ひげテンプレートを作成し、「resources/templates」フォルダーに配置します。
Hello {{firstName}} {{lastName}}!
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());
}
}
基本的にはそれだけです。Maven を使用してこれを設定すると、mvn install
ゴールの実行時にテストが実行され、合格するはずです。
この例のために作成したプロジェクト コードは次のとおりです: https://github.com/cosbor11/java-template-example
それが役に立てば幸い!
http://velocity.apache.org/engine/devel/をチェックしてください