freemarker模板在客服域的使用场景及用法介绍

🍊 Java学习:社区快速通道

🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想

🍊 绝对不一样的职场干货:大厂最佳实践经验指南


📆 最近更新:2023年7月15日


🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力!


文章目录

  • 基于模板文件的示例
  • 基于字符串的示例
    • Configuration.VERSION_2_3_31
  • 基于freemarker.template的小程序

freemarker.template是一个Java库,用于生成文本输出(如HTML、XML、邮件等),基于模板和数据模型。它的主要特点有:

  1. 模板语言简洁、强大、灵活,支持各种数据类型和控制结构,可以轻松地嵌入静态文本中。
  2. 数据模型可以是任何Java对象,也可以是专门为freemarker.template设计的简单哈希表或序列。
  3. 可以自定义模板加载器、缓存策略、输出格式、异常处理等,以适应不同的应用场景。
  4. 可以与各种Web框架和MVC架构集成,如Spring、Struts、Servlet等,也可以作为一个独立的组件使用。

因此不难想到,现在各个企业App的客服务域机器人的各种特色话术,就是非常适合使用此类技术的场景。如下图是拼多多客户和用户的一段聊天内容:
在这里插入图片描述

其中商家在6天15小时42分钟字样就可以由服务端计算并使用freemarker模板进行替换并展示给用户,这样就避免了重复配置多个不同的话术,有效地提高了效率。


基于模板文件的示例

首先,需要创建一个模板文件,命名为hello.ftl,内容如下:

<html>
<head>
    <title>${title}</title>
</head>
<body>
    <h1>${message}</h1>
    <ul>
        <#list users as user>
        <li>${user.name} (${user.age})</li>
        </#list>
    </ul>
</body>
</html>

这个模板文件中使用了freemarker.template的语法,其中${...}表示输出一个变量的值,<#list ...>表示循环遍历一个序列,并为每个元素赋值给一个局部变量。


然后,需要创建一个Java类,用于加载模板文件,并提供数据模型。假设这个类名为HelloFreemarker,内容如下:

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HelloFreemarker {

    public static void main(String[] args) throws IOException, TemplateException {
        // 创建一个Configuration实例
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);

        // 设置模板文件所在的目录
        cfg.setClassForTemplateLoading(HelloFreemarker.class, "/templates");

        // 获取模板对象
        Template template = cfg.getTemplate("hello.ftl");

        // 创建一个数据模型
        Map<String, Object> data = new HashMap<>();
        data.put("title", "Hello Freemarker");
        data.put("message", "This is a simple example of Freemarker template engine.");

        // 创建一个用户列表
        List<Map<String, Object>> users = new ArrayList<>();
        Map<String, Object> user1 = new HashMap<>();
        user1.put("name", "Alice");
        user1.put("age", 20);
        users.add(user1);
        Map<String, Object> user2 = new HashMap<>();
        user2.put("name", "Bob");
        user2.put("age", 25);
        users.add(user2);

        // 将用户列表放入数据模型中
        data.put("users", users);

        // 创建一个输出流
        Writer out = new OutputStreamWriter(System.out);

        // 将数据模型和模板文件合并,生成输出
        template.process(data, out);

        // 关闭输出流
        out.close();
    }
}

这个Java类中使用了freemarker.template的API,其中Configuration类用于配置模板引擎的各种参数,Template类用于表示模板文件对象,process方法用于将数据模型和模板文件合并,并输出到指定的流中。

最后,运行这个Java类,可以得到以下输出:

<html>
<head>
    <title>Hello Freemarker</title>
</head>
<body>
    <h1>This is a simple example of Freemarker template engine.</h1>
    <ul>
        <li>Alice (20)</li>
        <li>Bob (25)</li>
    </ul>
</body>
</html>

可以看到,通过使用模板文件和数据模型,可以方便地生成各种文本输出,而不需要在Java代码中拼接字符串。

基于字符串的示例

freemarker.template也支持从字符串中加载模板,只需要使用Template类的另一个构造方法,传入一个字符串和一个配置对象即可。例如:

// 创建一个模板字符串
String templateString = "<html>\n" +
        "<head>\n" +
        "    <title>${title}</title>\n" +
        "</head>\n" +
        "<body>\n" +
        "    <h1>${message}</h1>\n" +
        "    <ul>\n" +
        "        <#list users as user>\n" +
        "        <li>${user.name} (${user.age})</li>\n" +
        "        </#list>\n" +
        "    </ul>\n" +
        "</body>\n" +
        "</html>";
// 创建一个Configuration实例
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
// 从字符串中创建一个模板对象
Template template = new Template("template", templateString, cfg);

这样就可以使用字符串作为模板,其他的步骤和之前的示例相同。


Configuration.VERSION_2_3_31

Configuration.VERSION_2_3_31是一个常量,表示freemarker.template的版本号,用于指定Configuration对象的兼容性模式。可以是别的取值,但是要与你使用的freemarker.template的实际版本相匹配,否则可能会出现错误或警告。一般来说,建议使用最新的版本号,例如Configuration.VERSION_2_3_32


查看使用的freemarker.template的版本的方法:

  1. 通过Maven或Gradle等工具管理依赖:可以查看pom.xml或build.gradle文件中freemarker的版本号。
  2. 直接下载freemarker的jar包:可以查看jar包的文件名中的版本号,或者解压jar包后查看META-INF/MANIFEST.MF文件中的Bundle-Version属性。
  3. 在代码中使用freemarker:调用Configuration.getVersion()方法,返回一个Version对象,然后调用getMajor()getMinor()getMicro()等方法获取版本号。

基于freemarker.template的小程序

这个小程序的功能是根据用户输入的性别、爱好、职业等,然后根据这些信息生成更个性化的问候语,并显示在控制台上,此外还可以根据用户输入的语言,生成不同语言的问候语。使用freemarker.template的步骤如下:

  1. 导入freemarker.template的jar包,或者使用Maven或Gradle等工具添加依赖。
  2. 创建一个Configuration对象,设置模板文件所在的目录和编码方式。
  3. 创建一个模板文件,命名为greeting.ftl,内容如下:
<#-- greeting_en.ftl -->
<#-- Use cap_first and upper_case built-ins to format the name -->
Hello ${name?cap_first} ${name?upper_case}!

<#-- Use if-else directive to generate different messages based on gender -->
<#if gender == "male">
You are a ${age} years old man.
<#elseif gender == "female">
You are a ${age} years old woman.
<#else>
You are a ${age} years old person.
</#if>

<#-- Use switch directive to generate different messages based on occupation -->
<#switch occupation>
    <#case "student">
    You are studying hard for your future.
    <#break>
    <#case "teacher">
    You are teaching the next generation.
    <#break>
    <#case "doctor">
    You are saving lives every day.
    <#break>
    <#case "engineer">
    You are building amazing things.
    <#break>
    <#default>
    You are doing a great job.
</#switch>

<#-- Use hobby as a variable -->
Your hobby is ${hobby}.


代码实现逻辑:

  1. 创建一个数据模型,用一个Map对象存储用户输入的姓名和年龄。
  2. 获取模板对象,调用process方法,将数据模型和模板文件合并,并输出到一个输出流中。
  3. 关闭输出流。
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;

public class GreetingApp {

    public static void main(String[] args) throws IOException, TemplateException {
        // 创建一个Scanner对象,用于接收用户输入
        Scanner scanner = new Scanner(System.in);

        // 提示用户输入姓名、年龄、性别、爱好、职业和语言
        System.out.println("Please enter your name:");
        String name = scanner.nextLine();
        System.out.println("Please enter your age:");
        int age = scanner.nextInt();
        scanner.nextLine(); // consume the newline character
        System.out.println("Please enter your gender (male/female/other):");
        String gender = scanner.nextLine();
        System.out.println("Please enter your hobby:");
        String hobby = scanner.nextLine();
        System.out.println("Please enter your occupation:");
        String occupation = scanner.nextLine();
        System.out.println("Please enter your language (en/cn/fr/de):");
        String language = scanner.nextLine();

        // 创建一个Configuration对象,设置模板文件所在的目录和编码方式
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
        cfg.setClassForTemplateLoading(GreetingApp.class, "/templates");
        cfg.setDefaultEncoding("UTF-8");

        // 获取模板对象,根据用户输入的语言选择不同的模板文件
        Template template = null;
        switch (language) {
            case "en":
                template = cfg.getTemplate("greeting_en.ftl");
                break;
            case "cn":
                template = cfg.getTemplate("greeting_cn.ftl");
                break;
            case "fr":
                template = cfg.getTemplate("greeting_fr.ftl");
                break;
            case "de":
                template = cfg.getTemplate("greeting_de.ftl");
                break;
            default:
                System.out.println("Invalid language. Use English as default.");
                template = cfg.getTemplate("greeting_en.ftl");
                break;
        }

        // 创建一个数据模型,用一个Map对象存储用户输入的姓名、年龄、性别、爱好、职业和语言
        Map<String, Object> data = new HashMap<>();
        data.put("name", name);
        data.put("age", age);
        data.put("gender", gender);
        data.put("hobby", hobby);
        data.put("occupation", occupation);
        data.put("language", language);

        // 创建一个输出流
        Writer out = new OutputStreamWriter(System.out);

        // 将数据模型和模板文件合并,生成输出
        template.process(data, out);

        // 关闭输出流
        out.close();

        // 关闭Scanner对象
        scanner.close();
    }
}

运行这个小程序,可以得到以下的输出:

Please enter your name:
Tom
Please enter your age:
18
Please enter your gender (male/female/other):
male
Please enter your hobby:
reading
Please enter your occupation:
student
Please enter your language (en/cn/fr/de):
en
Hello Tom TOM!

You are a 18 years old man.

You are studying hard for your future.

Your hobby is reading.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/38640.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

垃圾收集器CMS-JVM(十一)

Jvm类的创建过程包括类的加载&#xff0c;类的验证&#xff0c;准备&#xff0c;分析&#xff0c;初始化。 验证是不是.class文件。 准备过程则是先赋值初始化的值&#xff0c;并不是直接赋值原始值。 分析比较复杂&#xff0c;会有静态链接处理和动态链接处理。 最后就是类…

uni-app:scroll-view滚动盒子,实现横(纵)向滚动条

参照&#xff1a;scroll-view | uni-app官网 (dcloud.net.cn) 样式&#xff1a; 代码&#xff1a; <template><view class"box"><scroll-view scroll-x"true" class"scroll"><view class"box1"> <view c…

使用Vue + FormData + axios实现图片上传功能实战

前言 上节回顾 上一小节中,我们添加了Vue-router的路有数据,这些数据都将是后续实战课程中的真实路由数据了。同时引入了ElementUI的el-menu做为左侧菜单的组件,但本专栏的特点就是遇到第三方功能和组件,自己尽量也要实现一遍,所以,在文章末尾又自己实现了一个tg-menu的…

Docker 安装 Nginx,并实现负载均衡

1、获取 nginx 的镜像 # 默认是latest版本docker pull nginx 2、运行 nginx 容器 docker run --name nginx-80 -p 80:80 --rm -d nginx# --name nginx-80 设定容器的名称# -p 80:80 端口进行映射&#xff0c;将本地的80端口映射到容器内部的80端口# --rm 表示容器退出后直接…

gogs的自定义配置

在 GOGS 下载并安装后&#xff0c;在程序目录下建立一个custom/conf/app.ini的配置文件&#xff0c;内容如下&#xff1a; APP_NAME Gogs # APP名字 RUN_USER git # 启动用户&#xff0c;设置后只能以此账号启动gogs RUN_MODE prod[database] DB_TYPE mysql HOST 1…

热门二叉树面试题

606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&a…

SpringCloud整合Sentinel

文章目录 1、Sentinel介绍2、安装Sentinel控制台3、微服务整合Sentinel 1、Sentinel介绍 阿里开源的流量控制组件官网&#xff1a;https://sentinelguard.io/zh-cn/index.html承接了阿里双十一大促流量的核心场景&#xff0c;如秒杀、消息削峰填谷、集群流量控制、实时熔断下游…

vue+relation-graph绘制关系图实用组件

先在终端执行命令 vue create relationgraph创建一个vue2的项目 然后在编辑器中打开新创建的项目 在终端中执行命令 npm install relation-graph --save引入依赖 这样 我们relation-graph就进来了 然后 我们在需要使用的组件中编写代码如下 <template><div>&…

MyBatis 系列2 -- 增加、删除、修改操作

1. 前言 上一系列介绍了MyBatis的背景,以及为什么我们使用MyBatis进行操作数据库,还实现了使用MyBatis进行查询数据库的,接下来我们继续将使用MyBatis操作数据库的其他三种基本操作进行总结. 目录 1. 前言 2. 增加用户操作 3. 修改用户操作 4. 删除用户操作 5. 多表查询操…

3. CSS-定位

absolute和relative依据什么定位? relative依据自身定位,absolute 依据最近一层的定位元素定位 (定位元素是指开启了absolute relative fixed的父元素,没有就是根元素body) 居中对齐的实现方式:详情看这篇博客

webpack-theme-color-replacer+elementui自定义配置主题色

webpack-theme-color-replacer原理是通过获取到配置数组里的颜色值&#xff0c;在触发换色方法时&#xff0c;elementui使用的颜色值存在与配置表中颜色一致的颜色&#xff0c;则改颜色会被替换成新的颜色值。 若是自定义的css文件&#xff0c;需要配置css文件路径 若是需要修…

如何应对黑产进行验证图片资源遍历

第一期&#xff0c;我们分享的攻防点是&#xff1a;验证图片资源遍历。 “遍历”指黑产通过穷举法获得所有验证码图片的答案&#xff0c;以便能在未来彻底无视验证码。由于验证码主要是通过图片语义答案来识别人机&#xff0c;因此攻破这层防御最有效的方式就是遍历该验证码图…

【数据结构】二叉树的前中后序遍历(C语言)

文章目录 什么是二叉树树相关的概念树的表示形式特殊的二叉树如何创造出一棵二叉树二叉树的遍历先序遍历(前序遍历)中序遍历后序遍历 总结 什么是二叉树 [二叉树] 顾名思义就是有两个分支节点的树&#xff0c;不仅如此&#xff0c;除了叶子外的所有节点都具有两个分支节点&…

matlab入门

命名规则&#xff1a; clc&#xff1a;清除命令行的所有命令 clear all&#xff1a;清除所有工作区的内容 注释&#xff1a;两个% 空格 %% matlab的数据类型 1、数字 3 3 * 5 3 / 5 3 5 3 - 52、字符与字符串 s a %% 求s的ascill码 abs(s) char(97) num2str(65) str I…

curl: (56) Recv failure : Connection reset by peer

文章目录 背景原因可能如下1. 服务器端关闭了连接2. 网络问题3. 防火墙或代理问题4. 服务器负载过高 解决办法 背景 docker容器里有http服务&#xff0c;今天在docker容器重启时&#xff0c;去调用http接口&#xff0c;出现了以下错误&#xff1a; curl: (56) Recv failure :…

记一次ruoyi中使用Quartz实现定时任务

一、首先了解一下Quartz Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目&#xff0c;它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个&#xff0c;百个&#xff0c;甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标…

Deepin/UOS Linux 桌面自定义 IDEA/DataGrip 应用程序图标

在 $HOME/Desktop目录下编辑 vim jetbrains.intelij.idea.desktop [Desktop Entry] TypeApplication NameIntelij IDEA Icon/opt/module/idea-IU-203.8084.24/bin/idea.png Exec/opt/module/idea-IU-203.8084.24/bin/idea.sh Terminalfalse CategoriesDevelopment;IDE;vim je…

自动化运维工具——Ansible学习(二)

目录 一、handlers和notify结合使用触发条件 1.新建httpd.yml文件 2.复制配置文件到ansible的files目录中 3.卸载被控机已安装的httpd 4.执行httpd.yml脚本 5.更改httpd.conf配置文件 6.使用handlers 7.重新执行httpd.yml脚本 8.检查被控机的端口号是否改变 9.handle…

Block

文章目录 前言Block本质Block循环引用解决循环引用1.__weak __strong协作2.__block3.参数传递 Block中对象的引用计数Block Copy__blockBlock的分类 前言 之前学过Block了&#xff0c;那就在学学 之前学习Block的博客 参考 提示&#xff1a;以下是本篇文章正文内容&#xff…

AtcoderABC249场

A - JoggingA - Jogging 题目大意 高桥和青木一起慢跑&#xff0c;高桥每隔 ACAC 秒钟走 BB 米&#xff0c;然后休息 CC 秒钟&#xff0c;青木每隔 DFDF 秒钟走 EE 米&#xff0c;然后休息 FF 秒钟。现在已经过去了 XX 秒钟&#xff0c;问谁跑得更远。 思路分析 模拟来解决这…