文档章节

superword中的模板抽取实践

杨尚川
 杨尚川
发布于 2016/04/02 22:28
字数 1202
阅读 694
收藏 8

superword这个项目,全使用JAVA8新特性: https://github.com/ysc/superword ,一开始只是我的一个英语单词分析工具,用于生成HTML片段然后发到博客中,后来功能越来越强于是我就做成一个项目了,再后来有人跟我说自己不是计算机专业的不会用这个软件,于是我就改造成了一个WEB项目,这个项目现在有点需要改进的地方,就是把JAVA代码生成HTML的这个逻辑改成使用FREEMARKER的方式

我们首先来看在org.apdplat.superword.system.AntiRobotFilter类中的原来的JAVA代码生成HTML的逻辑:

StringBuilder html = new StringBuilder();
html.append("<h1>The meaning of red color font is your answer, but the right answer is the meaning of blue color font for the word <font color=\"red\">")
        .append(quizItem.getWord().getWord())
        .append(":</font></h1>");
html.append("<h2><ul>");
for(String option : quizItem.getMeanings()){
    html.append("<li>");
    if(option.equals(_answer)) {
        html.append("<font color=\"red\">").append(option).append("</font>");
    }else if(option.equals(quizItem.getWord().getMeaning())){
        html.append("<font color=\"blue\">").append(option).append("</font>");
    }else{
        html.append(option);
    }
    html.append("</li>\n");
}
html.append("</ul></h2>\n<h1><a href=\"")
        .append(servletContext.getContextPath())
        .append("\">Continue...</a></h1>\n");

这样的代码对JAVA开发人员来说,第一次写的时候很爽很方便,用于原型开发快速验证功能是可以的,不过如果隔的时间长了自己再回头来看或者其他人来看这段代码,就会很吃力,因为这里纠缠了JAVA和HTML,纠缠了业务逻辑、数据处理逻辑以及显示逻辑,所以,如果代码需要持续维护的话就需要重构,下面我们就使用FREEMARKER来重构。

第一步,在pom.xml中引入FREEMARKER的依赖:

<!-- html模板引擎 -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>${freemarker.version}</version>
</dependency>
<freemarker.version>2.3.24-incubating</freemarker.version>

第二步,在类路径下的template/freemarker/identify_quiz.ftlh文件中定义HTML模板:

<h1>
    The meaning of red color font is your answer, but the right answer is the meaning of blue color font for the word <font color="red">${quizItem.word.word}:</font>
</h1>
<h2>
    <ul>
<#list quizItem.meanings as meaning>
    <#if meaning == answer>
    <#--  用户答案 -->
        <li><font color="red">${meaning}</font></li>
    <#elseif meaning == quizItem.word.meaning>
    <#--  正确答案 -->
        <li><font color="blue">${meaning}</font></li>
    <#else>
    <#--  其他选项 -->
        <li>${meaning}</li>
    </#if>
</#list>
    </ul>
</h2>
<h1>
    <a href="">Continue...</a>
</h1>

第三步,org.apdplat.superword.system.AntiRobotFilter类中准备模板需要的数据:

Map<String, Object> data = new HashMap<>();
data.put("quizItem", quizItem);
data.put("answer", _answer);

第四步,编写一个工具类org.apdplat.superword.freemarker.TemplateUtils,将模板和数据融合生成最终的HTML代码:

package org.apdplat.superword.freemarker;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.apdplat.superword.model.QuizItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

/**
 * 模板工具, 用于生成html代码
 * Created by ysc on 4/2/16.
 */
public class TemplateUtils {
    private TemplateUtils(){}
    private static final Logger LOGGER = LoggerFactory.getLogger(TemplateUtils.class);
    private static final Configuration CFG = new Configuration(Configuration.VERSION_2_3_23);

    static{
        LOGGER.info("开始初始化模板配置");
        CFG.setClassLoaderForTemplateLoading(TemplateUtils.class.getClassLoader(), "/template/freemarker/");
        CFG.setDefaultEncoding("UTF-8");
        if(LOGGER.isDebugEnabled()) {
            CFG.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        }else{
            CFG.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        }
        CFG.setLogTemplateExceptions(false);
        LOGGER.info("模板配置初始化完毕");
    }

    /**
     * 在识别用户是否是机器人的测试中, 如果用户测试失败, 则向用户显示这里生成的HTML代码
     * @param data 需要两个数据项, 一是测试数据集quizItem, 二是用户的回答answer
     * @return 测试结果HTML代码
     */
    public static String getIdentifyQuiz(Map<String, Object> data){
        try {
            Template template = CFG.getTemplate("identify_quiz.ftlh");
            Writer out = new StringWriter();
            template.process(data, out);
            return out.toString();
        }catch (Exception e){
            LOGGER.error("generate authentication template failed", e);
        }
        return "";
    }

    public static void main(String[] args) {
        Map<String, Object> data = new HashMap<>();
        QuizItem quizItem = QuizItem.buildIdentifyHumanQuiz(12);
        data.put("quizItem", quizItem);
        data.put("answer", "random answer");
        System.out.println(TemplateUtils.getIdentifyQuiz(data));
    }
}

第五步,org.apdplat.superword.system.AntiRobotFilter类中删除JAVA代码生成HTML的逻辑,转而使用如下代码:

Map<String, Object> data = new HashMap<>();
data.put("quizItem", quizItem);
data.put("answer", _answer);
String html = TemplateUtils.getIdentifyQuiz(data);


大功告成!看一下页面输出效果:


最后看一下模板引擎的日志输出,第一次访问:

开始初始化模板配置
模板配置初始化完毕
0    DEBUG [2016-04-02 22:04:25]  Couldn't find template in cache for "identify_quiz.ftlh"("en_US", UTF-8, parsed); will try to load it.
1    DEBUG [2016-04-02 22:04:25]  TemplateLoader.findTemplateSource("identify_quiz_en_US.ftlh"): Not found
2    DEBUG [2016-04-02 22:04:25]  TemplateLoader.findTemplateSource("identify_quiz_en.ftlh"): Not found
2    DEBUG [2016-04-02 22:04:25]  TemplateLoader.findTemplateSource("identify_quiz.ftlh"): Found
2    DEBUG [2016-04-02 22:04:25]  Loading template for "identify_quiz.ftlh"("en_US", UTF-8, parsed) from "file:/Users/ysc/workspace/superword/target/superword-1.0/WEB-INF/classes/template/freemarker/identify_quiz.ftlh"

第二次:

5324 DEBUG [2016-04-02 22:04:30]  TemplateLoader.findTemplateSource("identify_quiz_en_US.ftlh"): Not found
5325 DEBUG [2016-04-02 22:04:30]  TemplateLoader.findTemplateSource("identify_quiz_en.ftlh"): Not found
5325 DEBUG [2016-04-02 22:04:30]  TemplateLoader.findTemplateSource("identify_quiz.ftlh"): Found
5325 DEBUG [2016-04-02 22:04:30]  "identify_quiz.ftlh"("en_US", UTF-8, parsed): using cached since file:/Users/ysc/workspace/superword/target/superword-1.0/WEB-INF/classes/template/freemarker/identify_quiz.ftlh hasn't changed.

第三次:

81642 DEBUG [2016-04-02 22:05:47]  TemplateLoader.findTemplateSource("identify_quiz_en_US.ftlh"): Not found
81643 DEBUG [2016-04-02 22:05:47]  TemplateLoader.findTemplateSource("identify_quiz_en.ftlh"): Not found
81643 DEBUG [2016-04-02 22:05:47]  TemplateLoader.findTemplateSource("identify_quiz.ftlh"): Found
81643 DEBUG [2016-04-02 22:05:47]  "identify_quiz.ftlh"("en_US", UTF-8, parsed): using cached since file:/Users/ysc/workspace/superword/target/superword-1.0/WEB-INF/classes/template/freemarker/identify_quiz.ftlh hasn't changed.


这次重构的完整代码见:https://github.com/ysc/superword/commit/a46b48a352106143ce3a10964b1a98f45a961944,superword中还有一些地方需要做类似的重构,有兴趣的同学可以尝试一下,测试成功后欢迎在github上面给我发pull request.






© 著作权归作者所有

杨尚川

杨尚川

粉丝 1103
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
博客系统--SuperWord-blog

SuperWord没有采用多么牛逼,或者高大上的编程语言,而是采用最为流行的PHP+MYSQL。在整个软件架构上,以易用,快捷为出发点,希望能够给您带来极速体验。 SuperWord基本功能包括:前台用户浏...

汤姆大叔
2015/05/22
2.1K
0
superword中一次精彩的重构

我们先来看看需要重构的功能是一个下拉选择框,可任意选择11部词典中的一部,访问地址:http://123.56.99.179/select/dictionary-select.jsp?dict=RANDOMHOUSE,在HTML中的效果如下图所示: ...

杨尚川
2016/04/20
663
1
312个免费高速HTTP代理IP(能隐藏自己真实IP地址)

124.88.67.20:843190.36.223.93:8080117.147.221.38:8123122.228.92.103:3128183.247.211.159:8123124.88.67.35:81112.18.51.167:8123218.28.96.39:312849.94.160.198:3128183.207.228.114:8......

杨尚川
2015/04/12
4.7K
18
网络机器人的识别与攻防的经典案例(也即爬虫与反爬虫的经典案例)

本文我们介绍一个网络机器人的识别与攻防的经典案例(也即爬虫与反爬虫的经典案例)。使用到的代码见本人的superword项目: https://github.com/ysc/superword/blob/master/src/main/java/o...

杨尚川
2015/04/11
2.3K
0
前嗅ForeSpider教程:创建模板

今天,小编为大家带来的教程是:如何在前嗅ForeSpider中创建模板。主要内容有:模板的概念,模板的配置方式,模板的高级选项,具体内容如下: 一,模板的概念 模板列表的层级相当于网页跳转的...

forespider
02/20
15
0

没有更多内容

加载失败,请刷新页面

加载更多

无回路有向图的拓扑排序

因公司业务需要,在表单中每个字段都会配置自动计算,但自动计算公式中会引用到其他字段中的值。所以希望可以根据计算公式,优先计算引用的公式。所以最终使用了无回路有向图的扩扑排序来实现...

兜兜毛毛
53分钟前
5
0
如何抢占云栖大会C位?史上最强强强攻略来了

点击观看视频: APSARA云栖大会开发者情怀 原文链接 本文为云栖社区原创内容,未经允许不得转载。

阿里云官方博客
今天
6
0
Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现

作者 | 声东 阿里云售后技术专家<br /> 文章来源:Docker,点击查看原文。 <br />以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情。尤其是当我们基于似是而非的理解...

阿里巴巴云原生
今天
9
0
PHP7.3的新特性

2018年12月6日,PHP7.3正式版发布,在PHP7.2基础上进行了大量错误修复和安全优化,性能提升10%! 从目前的更新说明来看,PHP 7.3 并不是一个主打新特性的版本,包含更多的是 bug 修复。PHP 7...

迅睿CMS-PHP开源CMS程序
今天
8
0
Tomcat 应用中并行流带来的类加载问题

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/f-X3n9cvDyU5f5NYH6mhxQ 作者:肖铭轩、王道环 随着 Java8 的不断流行,越来越多的开发人员使用并行流(parallel)...

vivo互联网技术
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部