【问题标题】:Emoji's not working in offline chat when using Openfire to chat between two iOS devices (using a MySQL db)使用 Openfire 在两个 iOS 设备之间聊天(使用 MySQL 数据库)时,表情符号在离线聊天中不起作用
【发布时间】:2015-12-06 17:47:17
【问题描述】:

我对 Openfire 有疑问,尤其是对表情符号字符的支持。我在互联网上搜索发现为了支持表情符号,我必须将数据库和表的编码和排序规则更改为 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;  

所以在上面的语句中,我正在更改数据库和表的字符集和排序规则。接下来,我读到我应该更改 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 表),将执行以下代码:

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();
}

我不确定我现在可以尝试什么,或者是否有任何其他解决方法可以解决此问题。任何帮助将不胜感激。

提前致谢!

【问题讨论】:

  • 2 个问号?不是1或4?请提供SHOW CREATE TABLE
  • @RickJames 我提供了CREATE TABLE 输出。
  • 您说它“存储为 2 个问号”。但也许它存储正确,但获取不正确。请提供SELECT emoji, HEX(emoji) FROM tbl WHERE ...,以便我们查看表格中的十六进制。
  • @RickJames 我已将输出添加到您提供的查询中。
  • 嗯...F09F9880 是那个表情符号的十六进制。而且,由于stanzautf8mb4,所以在input 一侧和表格中一切正常。请提供连接语句和用于获取它的SELECT代码。

标签: mysql unicode xmpp openfire emoji


【解决方案1】:

经过进一步调查,我发现问题可能与 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,表情符号字符的插入开始工作了。

【讨论】:

  • 嗨,我已经尝试了一切。我需要你的帮助。我已经设置了 utf8mb4 服务器端。但它仍然存储问号。
猜你喜欢
  • 2015-03-06
  • 2016-08-29
  • 2014-01-09
  • 1970-01-01
  • 2021-10-20
  • 2023-03-24
  • 2016-08-02
  • 1970-01-01
  • 2022-01-19
相关资源
最近更新 更多