使用 Openfire 在两个 iOS 设备之间聊天时,表情符号在离线聊天中不起作用(使用 MySQL 数据库)
Emoji's not working in offline chat when using Openfire to chat between two iOS devices (using a MySQL db)
我对 Openfire 有疑问,尤其是对 emoji 字符的支持。我在互联网上搜索发现,为了支持表情符号,我必须将数据库和 tables 的编码和排序规则更改为 UTF-8 unicode (utf8mb4)。我已使用以下 SQL 命令完成此操作:
SET NAMES utf8mb4;
ALTER DATABASE openfire CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE ofOffline CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
所以在上面的语句中,我正在更改数据库的字符集和排序规则 table。接下来,我读到我应该更改 JDBC 驱动程序以支持 unicode。我的系统属性中的 "database.defaultProvider.serverURL" 条目具有以下值(使用 Openfire 管理网页):
jdbc:mysql://localhost:3306/openfire?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8
当我在两个在线用户之间发送带有表情符号的消息时,它完美无缺。当消息的接收者离线时,消息被存储到数据库中,这就是错误的地方:表情符号没有正确存储在数据库中(它存储为两个问号)。
我的 CREATE TABLE
语句如下所示:
CREATE TABLE `ofMessageArchive` (
`messageID` bigint(20) DEFAULT NULL,
`conversationID` bigint(20) NOT NULL,
`fromJID` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`fromJIDResource` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`toJID` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`toJIDResource` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`sentDate` bigint(20) NOT NULL,
`stanza` mediumtext COLLATE utf8mb4_unicode_ci,
`body` mediumtext COLLATE utf8mb4_unicode_ci,
KEY `ofMessageArchive_con_idx` (`conversationID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我尝试使用以下查询获取节文本(其中包含表情符号)(请注意,消息 73 仅包含一个字符:表情符号):
SELECT stanza, HEX(stanza) FROM ofOffline WHERE messageID = 73
这给了我(-
签名消息的左侧,十六进制值的右侧):
- F09F9880
在数据库中插入节时(特别是 ofOffline
table 存储要传递给离线用户的消息),将执行以下代码:
String msgXML = message.getElement().asXML();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(INSERT_OFFLINE);
pstmt.setString(1, username);
pstmt.setLong(2, messageID);
pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date()));
pstmt.setInt(4, msgXML.length());
pstmt.setString(5, msgXML);
pstmt.executeUpdate();
}
我不确定我现在可以尝试什么,或者是否有任何其他解决此问题的方法。任何帮助将不胜感激。
提前致谢!
经过更多调查,我发现问题可能与 Openfire 使用的 JDBC 驱动程序有关。似乎我的连接字符串参数没有被正确解析和使用,所以我更改了 conf/openfire.xml
中的 JDBC 连接驱动程序字符串并重新启动了服务器。现在,当我插入表情符号时,出现以下错误:
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80</...' for column 'stanza' at row 1
在搜索上述错误后,here 解释说我应该将以下内容添加到我的 MySQL 配置文件中:
[mysqld]
...
character-set-server = utf8mb4
此外,我可以从连接字符串中删除 characterEncoding
参数。完成这些更改后,重新启动 MySQL 和 openfire,Emoji 字符的插入开始工作了。
我对 Openfire 有疑问,尤其是对 emoji 字符的支持。我在互联网上搜索发现,为了支持表情符号,我必须将数据库和 tables 的编码和排序规则更改为 UTF-8 unicode (utf8mb4)。我已使用以下 SQL 命令完成此操作:
SET NAMES utf8mb4;
ALTER DATABASE openfire CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE ofOffline CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
所以在上面的语句中,我正在更改数据库的字符集和排序规则 table。接下来,我读到我应该更改 JDBC 驱动程序以支持 unicode。我的系统属性中的 "database.defaultProvider.serverURL" 条目具有以下值(使用 Openfire 管理网页):
jdbc:mysql://localhost:3306/openfire?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8
当我在两个在线用户之间发送带有表情符号的消息时,它完美无缺。当消息的接收者离线时,消息被存储到数据库中,这就是错误的地方:表情符号没有正确存储在数据库中(它存储为两个问号)。
我的 CREATE TABLE
语句如下所示:
CREATE TABLE `ofMessageArchive` (
`messageID` bigint(20) DEFAULT NULL,
`conversationID` bigint(20) NOT NULL,
`fromJID` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`fromJIDResource` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`toJID` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`toJIDResource` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`sentDate` bigint(20) NOT NULL,
`stanza` mediumtext COLLATE utf8mb4_unicode_ci,
`body` mediumtext COLLATE utf8mb4_unicode_ci,
KEY `ofMessageArchive_con_idx` (`conversationID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我尝试使用以下查询获取节文本(其中包含表情符号)(请注意,消息 73 仅包含一个字符:表情符号):
SELECT stanza, HEX(stanza) FROM ofOffline WHERE messageID = 73
这给了我(-
签名消息的左侧,十六进制值的右侧):
- F09F9880
在数据库中插入节时(特别是 ofOffline
table 存储要传递给离线用户的消息),将执行以下代码:
String msgXML = message.getElement().asXML();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(INSERT_OFFLINE);
pstmt.setString(1, username);
pstmt.setLong(2, messageID);
pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date()));
pstmt.setInt(4, msgXML.length());
pstmt.setString(5, msgXML);
pstmt.executeUpdate();
}
我不确定我现在可以尝试什么,或者是否有任何其他解决此问题的方法。任何帮助将不胜感激。
提前致谢!
经过更多调查,我发现问题可能与 Openfire 使用的 JDBC 驱动程序有关。似乎我的连接字符串参数没有被正确解析和使用,所以我更改了 conf/openfire.xml
中的 JDBC 连接驱动程序字符串并重新启动了服务器。现在,当我插入表情符号时,出现以下错误:
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80</...' for column 'stanza' at row 1
在搜索上述错误后,here 解释说我应该将以下内容添加到我的 MySQL 配置文件中:
[mysqld]
...
character-set-server = utf8mb4
此外,我可以从连接字符串中删除 characterEncoding
参数。完成这些更改后,重新启动 MySQL 和 openfire,Emoji 字符的插入开始工作了。