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

news2024/11/16 9:47:11

🍊 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.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零搭建秒杀服务

1. 前言 目的&#xff1a;该项目只用于技术交流&#xff0c;不用于过多商业用途。 适用&#xff1a;可用于简历亮点、毕业答辩等。 2. 项目成果 2.1 秒杀主页 包含5个功能点&#xff1a; ①、Product Name&#xff1a;秒杀商品名称 ②、Product Image&#xff1a;秒杀商…

Multiframe-to-Multiframe Network for Video Denoising

Multiframe-to-Multiframe Network for Video Denoising 摘要 现存方法&#xff1a;多相邻帧恢复一个干净帧&#xff0c;效果好但是由于按顺序去噪考虑可能造成视频闪烁&#xff1b; 本文&#xff1a;提出一个多帧对多帧的去噪模型&#xff0c;从连续噪声帧中恢复多个干净帧…

【通览一百个大模型】GLM(THU)

【通览一百个大模型】GLM&#xff08;THU&#xff09; 作者&#xff1a;王嘉宁&#xff0c;本文章内容为原创&#xff0c;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 订阅专栏【大模型&NLP&算法】可获得博主多年积累的全部NLP、大模型和算法干货资…

基础算法-【区间合并】

题目 给定 n 个区间 [li,ri]&#xff0c;要求合并所有有交集的区间。 注意如果在端点处相交&#xff0c;也算有交集。 输出合并完成后的区间个数。 例如&#xff1a;[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。 输入格式 第一行包含整数 n。 接下来 n行&#xff0c;每行…

《远见》阅读笔记

不同的环境&#xff0c;不同的职业&#xff0c;职业生涯的建议并没有什么不同 找到热爱的工作&#xff0c;建立热爱的生活 如何思考职业远景 如何分配时间 如何扩张人脉 职业生涯决策框架 三个部分 职场思维、框架、工具实用性建议和案例现实生活为基础&#xff0c;平衡职…

MacOS触控板缩放暂时失灵问题解决

我的系统版本为Monterey 12.5.1&#xff0c;亲测有效 直接创建脚本xxx.sh&#xff0c;并在终端执行脚本bash xxx.sh即可解决此问题&#xff0c;脚本内容如下&#xff1a; #!/bin/bashkillall Finder #kill Finder如不需要可以删除 killall Dock #kill Dock 如不需要可以删…

一文详细介绍什么是数据标注?

机器学习和深度学习算法都依赖于数据&#xff0c;为构建可靠的人工智能模型&#xff0c;需要为算法提供结构良好且标注良好的数据。 为了让机器学习算法学习如何完成特定任务&#xff0c;我们必须标注它们用于训练的数据。换句话说&#xff0c;标注数据很简单&#xff0c;但并不…

pytorch深度学习 之二 拟合数据 从线性到非线性

目的 深入了解线性回归的使用方法&#xff0c;使用非线性激活函数&#xff0c;同时使用pytorch的nn模块&#xff0c;最后使用神经网络来求解线性拟合&#xff0c;只有深入了解了基础&#xff0c;才能做出更高水平的东西。 上一章 神经网络梯度下降和线性回归 拟合定义数据 …

php代码审计15.3之phar伪协议与反序列化

文章目录 1、基础2、生成phar格式文件3、例子4、小试牛刀 1、基础 在漏洞的利用过程之中&#xff0c;我们需要先本地生成phar格式的文件&#xff0c;而生成phar格式的文件&#xff0c;需要将php.ini中的phar.readonly配置项配置为0或Off。目标服务器端是不必开启此配置&#x…

设计模式07-责任链模式

责任链模式属于行为设计模式&#xff0c;常见的过滤器链就是使用责任链模式设计的。 文章目录 1、真实开发场景的问题引入2、责任链模式讲解2.1 核心类及类图2.2 基本代码 3、利用构建者模式解决问题4、责任链模式的应用实例5、总结5.1 解决的问题5.2 使用场景5.3 优缺点 1、真…

计算机的工作原理(操作系统篇)

文章目录 1.操作系统的定位1.硬件2.驱动3.操作系统内核4.系统调用 2.进程3.PCB中有哪些描述进程的特征4.内存管理 1.操作系统的定位 先看一张图: 1.操作系统是最接近硬件的软件,是软件/硬件/用户之间交互的媒介; 2.操作系统起到一个管理的作用 1)对下,要管理硬件设备 2)对上,…

【100天精通python】Day4:运算符

目录 1 算数运算符 2 赋值运算符 3 比较&#xff08;关系运算符&#xff09; 4 逻辑运算符 5 位运算符 6 运算符的优先级 以下是一个完整的示例代码&#xff0c;用于计算学生三科成绩的分差和平均分&#xff1a; 1 算数运算符 Python中的算术运算符包括&#xff1a; 加…

如何在pd里设置win10虚拟机command+w关闭chrome浏览器的一个标签页

背景 在windows&#xff0c;我们知道 ctrlw 在chrome浏览器里可以关闭一个标签页&#xff0c;但是对于MacOS&#xff0c;pd的虚拟机里安装win10后&#xff08;pdparallel desktop)&#xff0c;commandw默认并不是料想中的相当于ctrlw关闭一个标签页&#xff0c;而是关闭所有的…

MPP概述

前言 最近忙于工作&#xff0c;有一段时间没更新自己的博客了&#xff0c;也就意味着囤积了一波需要梳理总结并记录的知识点&#xff0c;但可以保证的是所有都是零星的知识点&#xff0c;不会涉及工作内容。 一、MPP简介 MPP (Massively Parallel Processing)&#xff0c;即大…

Cisco学习笔记(CCNA)——Internetworking

Internetworking Internetworking Basics 什么是网络&#xff1f; 计算机网络&#xff1a;具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来 网络设备 Hub&#xff08;集线器&#xff09; 优点&#xff1a;便宜、操作简单 缺点&#xff1a;共享型、…

Set与Map的使用 + 二叉搜索树与哈希桶的大白话讲解和图解+完整代码实现(详细注释)

文章目录 前言一、Set与Map概念及场景模型纯Key模型Key-Value模型 Map 的使用Set 的使用 二、二叉搜索树什么是二叉搜索树代码实现二叉搜索树查找操作插入操作删除操作(难点)cur这个节点没有左子树(cur.left null)cur这个节点没有右子树(cur.right null)cur这个节点没有左右子…

springboot与rabbitmq的整合【演示5种基本交换机】

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;后端专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…

基于梯度下降的线性回归(Gradient Descent For Linear Regression)

概述&#xff1a; 梯度下降是很常用的算法&#xff0c;它不仅被用在线性回归上和线性回归模型、平方误差代价函数。在本次&#xff0c;我们要将梯度下降和代价函数结合。我们将用到此算法&#xff0c;并将其应用于具体的拟合直线的线性回归算法里。 梯度下降算法和线性回归算法…

Cell 子刊 | 深度睡眠脑电波调节胰岛素敏感性促进血糖调节

缺乏高质量的睡眠会增加一个人患糖尿病的风险。然而&#xff0c;为什么会这样仍然是一个不解之谜。 近期&#xff0c;加州大学伯克利分校的一组睡眠科学家的新发现为我们揭示了答案。研究人员在人体内发现了一种潜在的调控机制&#xff0c;解释了为什么夜间深度睡眠脑电波能够调…

数据结构(王道)——线性表之静态链表顺序表和链表的比较

一、静态链表 定义&#xff1a; 代码实现&#xff1a; 如何定义一个静态链表 静态链表的基本操作思路&#xff1a; 初始化静态链表&#xff1a; 静态链表的查找、插入、删除 静态链表总结&#xff1a; 二、顺序表和链表的比较 逻辑结构对比&#xff1a; 存储结构对比&#xff…