具体见博客:https://blog.csdn.net/hj12312/article/details/85677142
利用velocity模板引擎生成文件要求三点:
(1)编写好的模板;
(2)模板参数;
(3)最终生成的文件的路径。
这三点条件达到后,就可以根据模板生产代码、配置文件了。
但是呢,模板Template的获取,却分不同的场景,在实际应用中,一般分为三种:
(1)按绝对路径加载。即模板和文件生成器不在一起的,即当成两个项目放着,很多时候模板甚至放着git服务器上;
(2)按相对路径加载。即模板和文件生成器在一个项目中,并且模板还在resouces目录下;
(3)以jar包的方式加载。即模板在jar包中。(这种加载方式目前还没测试过)
下面直接上代码:
Generator.java
package cn.hj.generator.velocity;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
public class Generator {
protected static final Logger logger = LoggerFactory.getLogger(Generator.class);
private VelocityEngine velocityEngine;
//模板加载类型 1,resource模板加载 2、绝对路径模板加载 3、jar包模板价值
private Integer type;
private String jarPath;
public Generator() {
}
public Generator( String jarPath) {
this.jarPath = jarPath;
}
/**
*
* @param templateType 模板加载方式
* @param templatePath 模板路径
* @param filePath 生成的文件路径
* @param parameterMap 模板变量
* @throws Exception
*/
public void generator(Integer templateType, String templatePath, String filePath, Map parameterMap) throws Exception{
type=templateType;
if(type!=1&&type!=3){
throw new Exception("模板加载方式错误!");
}
init();
writer(templatePath,filePath,parameterMap);
}
/**
*
* @param templateType 模板加载方式
* @param filePathMap 文件路径集合,key为模板路径,value为生成的文件路径
* @param parameterMap 模板变量
* @throws Exception
*/
public void generator(Integer templateType,Map filePathMap,Map parameterMap) throws Exception{
type=templateType;
if(templateType==2){
writer(filePathMap,parameterMap);
}else{
init();
for(Map.Entry entry : filePathMap.entrySet()){
writer(entry.getKey(),entry.getValue(),parameterMap);
}
}
}
/**
* 扫描模板文件夹,生成文件夹下的所有模板
* @param dirPath 文件夹路径
* @param replaceMap 需要对文件路径替换的内容,将key替换成value
* @param parameterMap 模板变量
* @throws Exception
*/
public void generator(String dirPath,MapreplaceMap,Map parameterMap)throws Exception{
Map filePathMap=new HashMap<>();
List fileList=new ArrayList<>();
scan(dirPath,fileList);
filePathMap=constructFilePathMap(fileList,replaceMap);
generator(2,filePathMap,parameterMap);
}
private void init(){
if (null == velocityEngine) {
Properties p = new Properties();
p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
p.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
p.setProperty("file.resource.loader.unicode", "true");
if(type==3){
p.setProperty("jar.resource.loader.path", jarPath);
}
velocityEngine = new VelocityEngine(p);
}
}
private void writer(MapfilePathMap,Map parameterMap) throws Exception {
Properties p = new Properties();
p.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "");
p.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
p.setProperty("output.encoding", "UTF-8");
Velocity.init(p);
for(Map.Entry entry : filePathMap.entrySet()){
writer1(entry.getKey(),entry.getValue(), parameterMap);
}
}
private void writer(String templatePath,String filePath,Map parameterMap) throws Exception{
if(StringUtils.isBlank(templatePath)){
throw new NullPointerException("templatePath 不能为空!");
}
if(StringUtils.isBlank(filePath)){
throw new NullPointerException("filePath 不能为空!");
}
Template template = velocityEngine.getTemplate(templatePath, "UTF-8");
File file=new File(filePath);
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
template.merge(new VelocityContext(parameterMap), writer);
writer.close();
logger.info("模板:" + templatePath + "; 输出文件:" + filePath);
}
private void writer1(String templatePath,String filePath,Map parameterMap) throws Exception{
Template template = Velocity.getTemplate(templatePath,"UTF-8");
File file=new File(filePath);
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
template.merge(new VelocityContext(parameterMap), writer);
writer.close();
logger.info("模板:" + templatePath + "; 文件:" + templatePath);
}
private void scan(String dirPath,List fileList){
File dirFile=new File(dirPath);
for(File file:dirFile.listFiles()) {
if(file.isDirectory()) {
scan(file.getPath(),fileList);
}else{
fileList.add(file);
}
}
}
private Map constructFilePathMap(List fileList,MapreplaceMap){
Map filePathMap=new HashMap<>();
for(File file:fileList){
String templatePath=file.getPath();
String filePath=file.getPath();
for(Map.Entry entry : replaceMap.entrySet()){
filePath=filePath.replace(entry.getKey(),entry.getValue());
}
filePathMap.put(templatePath,filePath);
}
return filePathMap;
}
public static Logger getLogger() {
return logger;
}
public VelocityEngine getVelocityEngine() {
return velocityEngine;
}
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getJarPath() {
return jarPath;
}
public void setJarPath(String jarPath) {
this.jarPath = jarPath;
}
}
其中,最基础的是writer(String templatePath,String filePath,Map
private void writer(String templatePath,String filePath,Map parameterMap) throws Exception{
if(StringUtils.isBlank(templatePath)){
throw new NullPointerException("templatePath 不能为空!");
}
if(StringUtils.isBlank(filePath)){
throw new NullPointerException("filePath 不能为空!");
}
Template template = velocityEngine.getTemplate(templatePath, "UTF-8");
File file=new File(filePath);
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
template.merge(new VelocityContext(parameterMap), writer);
writer.close();
logger.info("模板:" + templatePath + "; 输出文件:" + filePath);
}
另一个基础方法是:writer1(String templatePath,String filePath,Map parameterMap),按绝对路径加载模板用的此方法。
private void writer1(String templatePath,String filePath,Map parameterMap) throws Exception{
Template template = Velocity.getTemplate(templatePath,"UTF-8");
File file=new File(filePath);
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
template.merge(new VelocityContext(parameterMap), writer);
writer.close();
logger.info("模板:" + templatePath + "; 文件:" + templatePath);
}
在使用绝对路径加载模板的时候,我还提供了一个方法,
generator(String dirPath,MapreplaceMap,Map parameterMap)。
该方法可以扫描模板所在的文件夹,最后生产的文件集合的结构和文件夹的结构保持一致。replaceMap是将模板路径的部分内容替换成生成的文件的路径。(该方法是我设计万能脚手架时的重要方法,万能脚手架的实现具体见博客:XXX)
测试:
现在,随便取一个文件夹“E:\\test”,最终输出的文件到“E:\\test5”中,代码如下:
Test1.java
import java.util.HashMap;
public class Test1 {
@Test
public void test() {
Generator generator=new Generator();
try {
HashMap repalceMap=new HashMap<>();
repalceMap.put("E:\\test","E:\\test5");
generator.generator("E:\\test",repalceMap,new HashMap<>());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下:
在测一下本地模板,即rescources文件夹下的模板的情况,具体如下:
Test2.java
package cn.hj.generator;
import cn.hj.generator.velocity.Generator;
import org.junit.Test;
import java.util.HashMap;
public class Test2 {
@Test
public void test() {
Generator generator=new Generator();
try {
generator.generator(1,"\\template\\test.java","E:\\test4\\template\\aaa.java",new HashMap<>());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下: