模板技术:
模板+数据 = 文本
JSP就是模板技术的体现:JSP + 数据(作用域中) =
HTML文件
freemarker:默认后缀ftl
velocity:默认后缀vm
模板技术:动态页面静态化,可以做代码生成器,邮件
/短信的发送模板
代码:
1.先new一个VelocityEngine(Engine:引擎)
2.拿到相应的模板(创一个hello.vm)
3.创建Velocity上下文(放数据的容器)
4.new一个StringWriter,模板与数据结合=输出到
一个字符流
VTL语法:
注释:## #* *#(多行注释)
获取数据: ${user} $user
变量设置:#set($person="Tom")
Easy(简单)Code(代码)--->简单的代码生成器(很多公
司都有自己的代码生成器)
3.代码生成器
咱们在写代码的时候,应该已经发现了,如果你还要做另外
一个模块,那么它们的基础代码都差不多,虽然我们直接拷
备过来修改使用也是可以的。但还是会觉得有点浪费时间,
所以我们可以做一个自己生成基础代码的功能,然后我们直
接生成,再添加其它的功能即可!
没有代码生成器的时候,如果添加部门模型domain,复制
IDepartmentService,修改类名,ctrl+f,进行人工替换
而使用了代码生成器就是先定义好模板,然后使用代码自动
修改类名,有代码参照模板进行指定内容自动替换
先用一个临时模型Dept,进行测试
注:写代码生成器前,先把项目进行备份,以免写出问题无
法挽回!
3.1.开发步骤
1.准备模板(把每个模块需要改的地方确定好)
2.确定所有模板的生成顺序
3.确定所有模板的生成位置
4.确定要生成的基本功能的domain(Dept)
5.根据Domain名称与模板结合,在相应位置生成文件
6.解决如果父文件夹不存在的问题
7.解决如果文件已经存在的问题
8.排错(有错先改模板)
3.2.准备模板
我需要生成多少个文件,我就得准备多少个模板
把所有Employee对应的文件都拷备一份到相应的位置(并改
名为Domain):
(注意:大写与小写的替换)
把模板中的文件进行修改
提示(大家要操作的时候小心小心再小心)
所有的(大写)Employee换成
D
o
m
a
i
n
所
有
的
(
小
写
)
e
m
p
l
o
y
e
e
换
成
{Domain} 所有的(小写)employee换成
Domain所有的(小写)employee换成{domain}
只留下一个最基础的name字段,其它的多余功能全部去掉
注意(Employee中关于部门的操作都需要
去掉)
替换的位置$不要值不要出现前后空格
3.3.确定顺序
/ /**
- 确定修改的顺序(这个顺序你根据自己的习惯决定即可
)
*
1.src/main/java/cn/itsource/pss/query/DomainQuery.ja
va
*
2.src/main/java/cn/itsource/pss/repository/DomainRep
ository.java
*
3.src/main/java/cn/itsource/pss/service/IDomainServi
ce.java
*
4.src/main/java/cn/itsource/pss/service/impl/DomainS
erviceImpl.java
*
5.src/main/java/cn/itsource/pss/web/controller/Domai
nController.java
*
6.src/main/test/cn/itsource/pss/service/DomainServic
eTest.java
- 7.src/main/webapp/js/model/domain.js
- 8.src/main/webapp/WEB-INF/views/domain/domain.jsp
*/
3.4.准备路径等
//准备拼接路径的常量,如果有更多文件有利于重复利用
private static final String SRC = “src/main/java/”;
private static final String PACKAGE =
“cn/itsource/pss/”;
private static final String TEST = "src/test/java
/";
private static final String WEBAPP =
“src/main/webapp/”;
//准备路径的拼接
private String[] paths ={
SRC+PACKAGE+“query/”, SRC+PACKAGE
+“repository/”, SRC+PACKAGE+“service/”,
SRC+PACKAGE+“service/impl/”, SRC+PACKAGE
+“web/controller/”, TEST+PACKAGE+“service/”,
WEBAPP+“js/model/”,WEBAPP+"WEB-
INF/views/domain/"
};
//准备所有模板名称(和路径顺序一致)
private String[] tempNames = {
“DomainQuery.java”,“DomainRepository.java”,"IDomainS
ervice.java",
“DomainServiceImpl.java”,“DomainController.java”,"Do
mainServiceTest.java",
“domain.js”,“domain.jsp”
};
//准备要生成的Domain(有可能同时生成多个)
private String[] domains = {“Dept”};
3.5.完成创建代码
//生成相应的文件
@Test
public void testCreate() throws Exception{
//创建模板应用上下文
VelocityContext context = new VelocityContext();
//一.遍历所有的Domain
for (int i = 0; i < domains.length; i++) {
//1.1拿到大写的domain
String domainBig = domains[i];
//1.2拿到小写的domain
String domainSmall = domainBig.substring
(0,1).toLowerCase() + domainBig.substring(1);
//System.out.println(domainBig);
//System.out.println(domainSmall);
//1.3设置上下文的替换名称
context.put(“Domain”,domainBig);
context.put(“domain”,domainSmall);
//二.遍历所有的路径
for (int j = 0; j < paths.length; j++) {
//2.1拿到相应的路径
String path =paths[j];
//2.2拿到相应的模板名称
String tempName = tempNames[j];
//2.3拼接回我们需要的位置文件
String realPath = (path +
tempName).replaceAll(“Domain”,domainBig).replaceAll
(“domain”,domainSmall);
//三.准备相应文件与模板进行组合
//3.1准备相应的文件(要生成的文件)
File file = new File(realPath);
// 如果父文件不存在,我们创建一个
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
//3.2拿到相应的模板(需要设置好编码)
Template template =
Velocity.getTemplate(“template/”+tempName,“UTF-8”);
FileWriter writer = new FileWriter
(file);
template.merge(context, writer);
writer.close();
}
}
}
3.6.解决$冲突问题
创建出来后我们运行,会发现domain.js会报错。原因是js中
有很多 , 而 这 些 ,而这些 ,而这些和Velocity中的$形成了冲突,我们可以使
用以下这种办法来进行解决:
domain.js修改
顶部加上:#set(
D
=
′
D = '
D=′’ ) -> 为$显示设置一个变量
进行替换
$( -> ${D}(
$. -> ${D}.
3.7.其它细节处理
先运行看效果,如果有问题,请先进行模板文件的修改,
再重新生成。直到最后功能可以成功!(记住:有错先改模板
)
完整代码如下(还解决了如果文件存在我们就不再覆盖的问
题):
package cn.itsource.pss.common;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.junit.Test;
import java.io.File;
import java.io.FileWriter;
public class CreateCodeTest {
/**
* 确定修改的顺序(这个顺序你根据自己的习惯决定
即可)
*
1.src/main/java/cn/itsource/pss/query/DomainQuery.ja
va
*
2.src/main/java/cn/itsource/pss/repository/DomainRep
ository.java
*
3.src/main/java/cn/itsource/pss/service/IDomainServi
ce.java
*
4.src/main/java/cn/itsource/pss/service/impl/DomainS
erviceImpl.java
*
5.src/main/java/cn/itsource/pss/web/controller/Domai
nController.java
*
6.src/main/test/cn/itsource/pss/service/DomainServic
eTest.java
* 7.src/main/webapp/js/model/domain.js
* 8.src/main/webapp/WEB-
INF/views/domain/domain.jsp
*/
//准备拼接路径的常量,如果有更多文件有利于重复利
用
private static final String SRC =
“src/main/java/”;
private static final String PACKAGE =
“cn/itsource/pss/”;
private static final String TEST =
“src/main/test/”;
private static final String WEBAPP =
“src/main/webapp/”;
//准备路径(拼接)
private String[] paths ={
SRC+PACKAGE+"query/", SRC+PACKAGE
+“repository/”, SRC+PACKAGE+“service/”,
SRC+PACKAGE+“service/impl/”, SRC
+PACKAGE+“web/controller/”, TEST+PACKAGE+“service/”,
WEBAPP+“js/model/”,WEBAPP+"WEB-
INF/views/domain/"
};
//准备所有模板名称(和路径顺序一致)
private String[] tempNames = {
“DomainQuery.java”,“DomainRepository.java”,"IDomainS
ervice.java",
“DomainServiceImpl.java”,“DomainController.java”,"Do
mainServiceTest.java",
“domain.js”,“domain.jsp”
};
//准备要生成的Domain(有可能同时生成多个)
private String[] domains = {"Dept"};
//是否需要覆盖已经存在的文件 false代表不覆盖,一
般就用这个
//true代表覆盖,危险操作
private static final boolean FLAG = false;
//生成相应的文件
@Test
public void testCreate() throws Exception{
//创建模板应用上下文
VelocityContext context = new
VelocityContext();
//一.遍历所有的Domain
for (int i = 0; i < domains.length; i++) {
//1.1拿到大写的domain
String domainBig = domains[i];
//1.2拿到小写的domain
String domainSmall =
domainBig.substring(0,1).toLowerCase() +
domainBig.substring(1);
//System.out.println(domainBig);
//System.out.println(domainSmall);
//1.3设置上下文的替换名称
context.put(“Domain”,domainBig);
context.put(“domain”,domainSmall);
//二.遍历所有的路径
for (int j = 0; j < paths.length; j++) {
//2.1拿到相应的路径
String path =paths[j];
//2.2拿到相应的模板名称
String tempName = tempNames[j];
//2.3拼接回我们需要的位置文件
String realPath = (path +
tempName).replaceAll(“Domain”,domainBig).replaceAll
(“domain”,domainSmall);
//三.准备相应文件与模板进行组合
//3.1准备相应的文件(要生成的文件)
File file = new File(realPath);
// 如果文件存在,我们根据情况看是否
需要覆盖
if (file.exists() && !FLAG){
return;
}
// 如果父文件不存在,我们创建一个
File parentFile =
file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
System.out.println
(file.getAbsoluteFile()); //查看生成路径
//3.2拿到相应的模板(需要设置好编码)
Template template =
Velocity.getTemplate(“template/”+tempName,“UTF-8”);
FileWriter writer = new FileWriter
(file);
template.merge(context, writer);
writer.close();
}
}
}
}
如果代码生成器生成的文件有问题(错误),找到错误,修改
模板,重新生成 -> 一直到生成没有问题为止(慢慢调)
上面是咱们以前代码生成器的开发方案,现在咱们使用一个
idea的插件(EasyCode)来完成相应的代码生成功能(前提
是需要会Velocity的技术)。
对于EasyCode也是有相应文档可以查询(需要联网)!