`

superword中的模板抽取实践

阅读更多

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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的依赖:

1
2
3
4
5
6
<!-- html模板引擎 -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>${freemarker.version}</version>
</dependency>
1
<freemarker.version>2.3.24-incubating</freemarker.version>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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类中准备模板需要的数据:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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的逻辑,转而使用如下代码:

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

 

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

 

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

1
2
3
4
5
6
7
开始初始化模板配置
模板配置初始化完毕
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"

第二次:

1
2
3
4
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.

第三次:

1
2
3
4
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.

 

 

 

 

 

1
5
分享到:
评论

相关推荐

    抽取jfroum自带BBCode模板

    BBCode(Bulletin Board Code)是一种轻量级的标记语言,常用于网络论坛、社区等...在实际操作中,可能会遇到各种挑战,如模板解析的复杂性、源码结构的不透明性等,但通过逐步分析和实践,这些问题都可以迎刃而解。

    基于相似计算的信息抽取模板自动获取方法.pdf

    该方法的核心在于利用相似计算从未经标注的大规模文本数据中自动学习信息抽取模板。首先,需要一个种子模板作为起点,种子模板通常包含特定领域的关键实体类型和特征词。特征词是指在实例中频繁出现且具有领域代表性...

    20210504_时间增量抽取数据到本地ES中.kjb

    kettle抽取MySQL 增量数据 到 ES中 kettle抽取MySQL 增量数据 到 ES中 kettle抽取MySQL 增量数据 到 ES中 kettle抽取MySQL 增量数据 到 ES中 kettle抽取MySQL 增量数据 到 ES中 kettle抽取MySQL 增量数据 到 ES中 ...

    基于Deep Belief Nets 的中文名实体关系抽取

    在信息抽取领域,关系抽取是指从文本中识别两个实体之间的语义关系。在中文名实体关系抽取中,DBN可以用来检测和分类中文名实体之间的关系。DBN的优点是可以learning高维特征表示,并且可以capture复杂的关系模式。 ...

    基于python实现中文医学文本实体关系抽取源码+数据集+项目说明.zip

    同时相比于医学教材,临床实践文本指代关系明显,往往一段话中不会直接提及该主题疾病,因此针对临床实践类语料进行预处理,设计规则在每句之前增加主题疾病实体,并以@和原文分割。抽取语料时,如果三元组来源于...

    ETL中的数据增量抽取机制研究

    ### ETL中的数据增量抽取机制研究 #### 一、引言 随着大数据时代的到来,数据仓库作为企业数据管理和分析的核心...通过对不同机制的深入研究和实践探索,可以更好地满足企业在数据仓库建设和运营过程中的多样化需求。

    论文研究-基于多实例多标签BLSTM神经网络的中文关系抽取 .pdf

    中文关系抽取是指从中文文本中识别出实体之间的关系,是自然语言处理(NLP)中的一个重要研究领域。近年来,深度学习模型尤其在这一领域中显示出了强大的能力,但是针对中文关系抽取的研究却相对较少。唐慧和欧阳柳...

    基于Python的中文信息实体抽取、关系抽取、事件抽取源码+数据集+训练好的模型+项目说明.zip

    基于Python的中文信息实体抽取、关系抽取、事件抽取源码+数据集+训练好的模型+项目说明.zip 数据、预训练模型、训练好的模型下载地址: 链接:https://pan.baidu.com/s/1TdJOF7vjLw4caE1SkZEZGA?pwd=gdpq 提取码...

    基于双向循环神经网络和CRF特征模板的信息抽取python源码.zip

    基于双向循环神经网络和CRF特征模板的信息抽取python源码.zip基于双向循环神经网络和CRF特征模板的信息抽取python源码.zip基于双向循环神经网络和CRF特征模板的信息抽取python源码.zip基于双向循环神经网络和CRF特征...

    中文信息抽取关键技术研究与实现.pdf

    信息抽取技术应运而生,它能够自动地从非结构化或半结构化的文本数据中抽取结构化的信息。本文主要围绕中文信息抽取的关键技术进行研究,并设计实现了多个面向不同领域的信息抽取实验系统。 #### 二、关键技术研究...

    中文事件抽取技术的研究

    中文事件抽取技术的研究,中文事件抽取技术的研究

    场景是需要按照给出的模板抽取各excel->sheet1的正文(除开表头和表尾)内容

    本文将详细讲解如何按照给定的模板从多个Excel文件的Sheet1中抽取正文内容,并介绍一个已经编译好的程序——"Excel智能抽取程序",以及其使用方法和模拟数据。 首先,我们要理解“正文内容”通常指的是去除表头和...

    基于Oracle_Linux环境数据抽取技术的研究与实践

    ### 基于Oracle_Linux环境数据抽取技术的研究与实践 #### 一、研究背景与意义 随着信息技术的发展,企业面临着海量数据的管理和利用问题。数据仓库作为一种重要的数据分析工具,在现代企业的决策支持系统中扮演着...

    中文事件抽取技术研究1

    《中文事件抽取技术研究》这篇论文探讨了信息抽取领域中的关键任务——事件抽取,特别是针对中文文本的事件抽取。事件抽取旨在从非结构化的文本中提取出事件信息,并转化为结构化的表示,这对于自动文摘、自动问答和...

    论文研究-面向DeepWeb数据自动抽取的模板生成方法.pdf

    研究如何从一系列同模板生成的页面中生成该模板,并利用模板自动抽取数据。给出了模板生成问题的形式化描述,提出了一种新颖的模板生成方法,利用生成的模板从实例网页中抽取数据。与现有方法相比,该方法适用于列表...

    电信设备-一种采用模板方式抽取结构化信息的方法.zip

    本资料“电信设备-一种采用模板方式抽取结构化信息的方法”将深入探讨如何利用模板方法有效地从非结构化的电信设备数据中提取出有价值的信息。 首先,我们需要理解什么是结构化信息。结构化信息是指数据以预定义...

    基于深度学习的开源中文事件抽取算法汇总.zip

    总之,“基于深度学习的开源中文事件抽取算法汇总”为研究者和实践者提供了深入理解和应用事件抽取的强大工具,通过深度学习技术,我们可以更有效地从大量中文文本中抽取出有价值的事件信息,推动人工智能在信息处理...

    Python-cocoNLP中文信息抽取工具包

    这款工具包旨在帮助开发者和研究人员高效地从大量中文文本中抽取出有价值的信息,如实体识别、关系抽取、关键词提取等关键任务。在当今大数据时代,对中文文本进行深度分析的需求日益增长,cocoNLP的出现正好满足了...

Global site tag (gtag.js) - Google Analytics