Freemarker在项目的应用
在我的项目中,我要做的是一个医疗管理系统中的预约模块,当我们点击预约按钮后,系统会展示给我们预
约详列表(就是我们可以选择其中的预约项),其中,当我们每次点击预约进入到这个页面的时候我们都会
进入到数据库中进行一次查询,这对于我们的系统开销产生很大的影响。所以我们可以通过Freemarker产
生静态页面。
由此分析,我们产生的几个问题需要注意?
1、什么时候用这个Freemarker生成静态页面比较合适呢?
2、静态页面应该生成到什么位置呢?
3、应该生成几个静态页面呢?
面对第一个问题,我们首先要想到的是,我们生成了静态页面,当我们对预约详情进行增删改的时候,
静态页面就已经废了,因为我们增删改后的数据可能和静态页面的数据可能不太一样了。
第二个问题:当我们测试开发的时候我们首先要放在目录下的html所在的目录下。当我们可已将页面生成到
项目运行的tomcat下
第三个问题:当我们点击预约后进入到的是预约列表页面(比如一般检查或者内科检查等等),这个页面只
需要一个,在预约列表页面我们比如选择了一般检查,进入的页面就是包含了一般检查的详情,比如一般检查
都包含什么项目等等。这种页面我们每一种都要生成一个静态页面。
为了更好地让大家明白项目的结构请看下面的截图:
下面我们进行我们项目的开发首先我们添加依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
配置yml
spring:
application:
name: XXXX
#数据源配置 注意:复制使用的时候将yml中的注释全部删掉,否则可能报错
freemarker:
suffix: .ftl
charset: UTF-8
content-type: text/html
allow-request-override: true
allow-session-override: true
expose-request-attributes: true
expose-session-attributes: true
expose-spring-macro-helpers: true
prefer-file-system-access: false
#这里我们容易出现问题然后报错,我们尽量将ftl文件放在resource的templates文件夹下
#这里是设置我们读取ftl文件的路径。
template-loader-path: classpath:/templates
settings:
template_update_delay: 1
default_encoding: UTF-8
classic_compatible: true
date_format: yyyy-MM-dd
time_format: HH:mm:ss
datetime_format: yyyy-MM-dd HH:mm:ss
number_format: 0.##
#注意 下面配置的路径为绝对路径
out_put_path: 这里配置我们想要将生成的静态页面生成的地方。一般我们放在我们html所在的页面,我的页面是在resource下的static下的page页面
这个是预约列表的ftl文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no,minimal-ui">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../img/asset-favico.ico">
<title>预约</title>
<link rel="stylesheet" href="../css/page-health-order.css" />
</head>
<body data-spy="scroll" data-target="#myNavbar" data-offset="150">
<div class="app" id="app">
<!-- 页面头部 -->
<div class="top-header">
<span class="f-left"><i class="icon-back" onclick="history.go(-1)"></i></span>
<span class="center">传智健康</span>
<span class="f-right"><i class="icon-more"></i></span>
</div>
<!-- 页面内容 -->
<div class="contentBox">
<div class="list-column1">
<ul class="list">
<#list setmealList as setmeal>
<li class="list-item">
<a class="link-page" href="setmeal_detail_${setmeal.id}.html">
<img class="img-object f-left"
src="http://puco9aur6.bkt.clouddn.com/${setmeal.img}"
alt="">
<div class="item-body">
<h4 class="ellipsis item-title">${
setmeal.name}</h4>
<p class="ellipsis-more item-desc">${
setmeal.remark}</p>
<p class="item-keywords">
<span>
<#if setmeal.sex == '0'>
性别不限
<#else>
<#if setmeal.sex == '1'>
男
<#else>
女
</#if>
</#if>
</span>
<span>${
setmeal.age}</span>
</p>
</div>
</a>
</li>
</#list>
</ul>
</div>
</div>
</div>
<!-- 页面 css js -->
<script src="../plugins/vue/vue.js"></script>
<script src="../plugins/vue/axios-0.18.0.js"></script>
</body>
这个是每个列表中详情的的ftl文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no,minimal-ui">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../img/asset-favico.ico">
<title>预约详情</title>
<link rel="stylesheet" href="../css/page-health-orderDetail.css" />
<script src="../plugins/vue/vue.js"></script>
<script src="../plugins/vue/axios-0.18.0.js"></script>
<script src="../plugins/healthmobile.js"></script>
</head>
<body data-spy="scroll" data-target="#myNavbar" data-offset="150">
<div id="app" class="app">
<!-- 页面头部 -->
<div class="top-header">
<span class="f-left"><i class="icon-back" onclick="history.go(-1)"></i></span>
<span class="center">传智健康</span>
<span class="f-right"><i class="icon-more"></i></span>
</div>
<!-- 页面内容 -->
<div class="contentBox">
<div class="card">
<div class="project-img">
<img src="http://puco9aur6.bkt.clouddn.com/${setmeal.img}"
width="100%" height="100%" />
</div>
<div class="project-text">
<h4 class="tit">${
setmeal.name}</h4>
<p class="subtit">${
setmeal.remark}</p>
<p class="keywords">
<span>
<#if setmeal.sex == '0'>
性别不限
<#else>
<#if setmeal.sex == '1'>
男
<#else>
女
</#if>
</#if>
</span>
<span>${
setmeal.age}</span>
</p>
</div>
</div>
<div class="table-listbox">
<div class="box-title">
<i class="icon-zhen"><span class="path1"></span><span class="path2"></span></i>
<span>套餐详情</span>
</div>
<div class="box-table">
<div class="table-title">
<div class="tit-item flex2">项目名称</div>
<div class="tit-item flex3">项目内容</div>
<div class="tit-item flex3">项目解读</div>
</div>
<div class="table-content">
<ul class="table-list">
<#list setmeal.setmealCheckgroupList as checkgroup>
<li class="table-item">
<div class="item flex2">${
checkgroup.name}</div>
<div class="item flex3">
<#list checkgroup.checkgroupCheckitemList as checkitem>
<label>
${
checkitem.name}
</label>
</#list>
</div>
<div class="item flex3">${
checkgroup.remark}</div>
</li>
</#list>
</ul>
</div>
<div class="box-button">
<a @click="toOrderInfo()" class="order-btn">立即预约</a>
</div>
</div>
</div>
</div>
</div>
<script>
var vue = new Vue({
el:'#app',
methods:{
toOrderInfo(){
window.location.href = "orderInfo.html?id=${setmeal.id}";
}
}
});
</script>
</body>
当我我们添加详情列表的时候我们就要生成静态页面,详细代码如下:
@Override
public Result addSetmeal(Setmeal setmeal, int[] checkgroupIds) {
try {
int insert = setmealMapper.insert(setmeal);
if(checkgroupIds != null && checkgroupIds.length > 0 ){
for(Integer checkgroupId :checkgroupIds){
SetmealCheckgroup setmealCheckgroup = new SetmealCheckgroup();
setmealCheckgroup.setSetmealId(setmeal.getId());
setmealCheckgroup.setCheckgroupId(checkgroupId);
setmealCheckgroupMapper.insert(setmealCheckgroup);
}
generateMobileStaticHtml();
}
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.ADD_SETMEAL_FAIL,null);
}
return new Result(true, MessageConstant.ADD_SETMEAL_SUCCESS,null);
}
//生成静态页面
public void generateMobileStaticHtml() {
//准备模板文件中所需的数据
List<Setmeal> setmealList = (List<Setmeal>) this.getAllSetmeal().getData();
//生成套餐列表静态页面
generateMobileSetmealListHtml(setmealList);
//生成套餐详情静态页面(多个)
generateMobileSetmealDetailHtml(setmealList);
}
//生成套餐列表静态页面
public void generateMobileSetmealListHtml(List<Setmeal> setmealList) {
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("setmealList", setmealList);
this.generateHtml("mobile_setmeal.ftl","m_setmeal.html",dataMap);
}
//生成套餐详情静态页面(多个)
public void generateMobileSetmealDetailHtml(List<Setmeal> setmealList) {
for (Setmeal setmeal : setmealList) {
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("setmeal", this.findById(setmeal.getId()));
this.generateHtml("mobile_setmeal_detail.ftl",
"setmeal_detail_"+setmeal.getId()+".html",
dataMap);
}
}
public void generateHtml(String templateName,String htmlPageName,Map<String, Object> dataMap){
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Writer out = null;
try {
// 加载模版文件
Template template = configuration.getTemplate(templateName);
// 生成数据
File docFile = new File(outputpath + "\\" + htmlPageName);
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
// 输出文件
template.process(dataMap, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != out) {
out.flush();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
下面是对应的文件路径以及产生的静态页面的结果、大家看代码分析,不清楚的加我的v。
G654377984