一、获取模板
//Template getTemplate(String name)
//name:文件名
//去配置的默认的模板加载路径(template-loader-path)下查找文件
Template template=configuration.getTemplate("questionnairePreview.ftl")
二、合并模板和数据模型
1、生成 html/ftl 字符串
1、API
String htmlText=FreeMarkerTemplateUtils.processTemplateIntoString(Template template, Object model)
//model:一般Map、实体类
//生成的html字符串引入外部css、js时和自己写html引入一样,因为输出html时,那些src相当于还是在向本项目发起请求,css、js还是可以请求到
2、例子-预览
- 模板
<div id="app"> <#list qteList as qte> <el-row> <span class="row-text"> ${qte.name} </span> <a href='${qte.url}'>开始答卷</a> </el-row> </#list> </div>
- 数据模型+组装
//项目的context-path @Value("${server.servlet.context-path}") private String projectVisitPath; @GetMapping("preview/{id}") public String preview(HttpServletResponse response, @PathVariable(value="id",required=false) Integer id){ //获取模板 String templateFile; //首页模板 if(id==null){ templateFile="index.ftl"; }else{//内容页模板 templateFile="content.ftl"; } Template template=configuration.getTemplate(templateFile); /** * 该url就是请求预览接口的url * 根据模板生成的html字符串中的跳转url,其实就是向预览接口发起一次请求,再次生成html字符串 * 有时候url后面会跟随一个id,后台根据该id获取预览需要组装的信息,如:模板、内容等 */ RequestMapping requestMapping=SyConfigController.class.getAnnotation(RequestMapping.class); String classUrl=requestMapping.value()[0]; String url=projectVisitPath+classUrl+"/preview/"; //数据模型 Map<String,Object> model=new HashMap<>(); //一般首页id=null if(id==null){ model.put("qteList",new ArrayList<Map<String,Object>>(){{ for(int i=0;i<3;i++){ //模拟id final int id=i+1; add( new HashMap<String,Object>(){{ put("name","kimi"); put("url",url+id); }} ); } }}); }else{//内容页 model=mapper.queryById(id); } String htmlText=FreeMarkerTemplateUtils.processTemplateIntoString(template, model); /** * 设置Content-Type * 虽然设置的是text/html,也能解析css、js * 要通过设置header的方式设置;如果使用response.setContentType("text/html;charset=UTF-8")输出的是xml,浏览器显示一堆错误,原因就是不识别html的内容 */ response.setHeader("Content-Type","text/html;charset=UTF-8"); PrintWriter pintWriter=response.getWriter(); pintWriter.write(htmlText); pintWriter.close(); return null; }
2、生成html/ftl文件
1、 API
void template.process(data,new OutputStreamWriter(new FileOutputStream("static/web/index.html、index.ftl")));
//执行完成后自动调用out.flush()
//生成的html文件引入外部css、js时和自己写html引入一样,因为访问html时,那些src相当于还是在向本项目发起请求,css、js还是可以请求到
2.、例子-发布
-
模板
<div id="app"> <#list qteList as qte> <el-row> <span class="row-text"> ${qte.name} </span> <button @click="startQte('${qte.url}')">开始答卷</button> </el-row> </#list> </div> <script type="text/javascript"> new Vue({ el: '#app', name: "Index", data(){ return{ //发布生成的模板可能还需要动态数据,每次转发该到模板时数据模型不一样 rsId: ${r"${rsId}"} } }, methods:{ //start qte startQte(url){ url+=this.rsId window.location.href=url } } }) </script>
-
数据模型+组装
//项目的context-path @Value("${server.servlet.context-path}") private String projectVisitPath; String path="web"; //创建生成文件的目录 /** * 该url就是请求转发接口的url * 根据模板生成的html字符串中的跳转url,其实就是向后台接口发起一次请求,后台组装数据模型+转发视图 */ RequestMapping requestMapping=AnswerSheetController.class.getAnnotation(RequestMapping.class); String classUrl=requestMapping.value()[0]; String url=projectVisitPath+classUrl+"/start/"; //数据模型 Map<String,Object> model=new HashMap<>(); model.put("qteList",new ArrayList<Map<String,Object>>(){{ for(int i=0;i<3;i++){ //模拟id final int id=i+1; add( new HashMap<String,Object>(){{ put("name","kimi"); put("url",url+id); }} ); } }}); //加载模板 Template template=configuration.getTemplate("index.ftl"); //生成 String pathFile=path+"/web.ftl"; template.process(data,new OutputStreamWriter(new FileOutputStream(pathFile)));