http://xiangai.taobao.com
http://shop148612228.taobao.com

java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column '*****' at row 1

使用Mysql服务器的utf8字符编码,在存入移动端emoji表情时会报异常:

  1.  
    Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x84' for column 'content' at row 1
  2.  
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
  3.  
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
  4.  
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
  5.  
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
  6.  
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
  7.  
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
  8.  
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
  9.  
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)

原因:mysql的utf8编码的一个字符最多3个字节,但是一个emoji表情为4个字节,所以utf8不支持存储emoji表情,导致报错.

解决办法:

一.服务器端转换数据库存储编码

 数据库目前采用的编码为UTF8, 转换为可支持4个字节的utf8mb4_unicode编码。

如图所示:


       利:客户端存储和请求数据的时候不需要都去做转换
       弊:1)转换编码格式可能会导致现有数据库的数据发生乱码;
              2)转换编码格式之后,可能对后续的全文搜索功能有影响,大多数中文搜索引擎支持的编码格式为UTF-8;
              3)若Android端的编码与数据库转换后的编码不符,将对Android端产生同样的问题。

二.客户端转换编码

客户端输入内容时候,统一存储为服务端数据库支持的编码;客户端请求内容的时候,需要根据客户端支持的编码对请求到的数据进行相应的转换

      如代码所示:

  1.  
    public class EmojiConverterUtil {
  2.  
     
  3.  
    /**
  4.  
    * @Description 将字符串中的emoji表情转换成可以在utf-8字符集数据库中保存的格式(表情占4个字节,需要utf8mb4字符集)
  5.  
    * @param str
  6.  
    * 待转换字符串
  7.  
    * @return 转换后字符串
  8.  
    * @throws UnsupportedEncodingException
  9.  
    * exception
  10.  
    */
  11.  
    public static String emojiConvert1(String str)
  12.  
    {
  13.  
    String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
  14.  
     
  15.  
    Pattern pattern = Pattern.compile(patternString);
  16.  
    Matcher matcher = pattern.matcher(str);
  17.  
    StringBuffer sb = new StringBuffer();
  18.  
    while(matcher.find()) {
  19.  
    try {
  20.  
    matcher.appendReplacement(
  21.  
    sb,
  22.  
    "[["
  23.  
    + URLEncoder.encode(matcher.group(1),
  24.  
    "UTF-8") + "]]");
  25.  
    } catch(UnsupportedEncodingException e) {
  26.  
    }
  27.  
    }
  28.  
    matcher.appendTail(sb);
  29.  
    return sb.toString();
  30.  
    }
  31.  
     
  32.  
    /**
  33.  
    * @Description 还原utf8数据库中保存的含转换后emoji表情的字符串
  34.  
    * @param str
  35.  
    * 转换后的字符串
  36.  
    * @return 转换前的字符串
  37.  
    * exception
  38.  
    */
  39.  
    public static String emojiRecovery2(String str){
  40.  
    String patternString = "\\[\\[(.*?)\\]\\]";
  41.  
     
  42.  
    Pattern pattern = Pattern.compile(patternString);
  43.  
    Matcher matcher = pattern.matcher(str);
  44.  
     
  45.  
    StringBuffer sb = new StringBuffer();
  46.  
    while(matcher.find()) {
  47.  
    try {
  48.  
    matcher.appendReplacement(sb,
  49.  
    URLDecoder.decode(matcher.group(1), "UTF-8"));
  50.  
    } catch(UnsupportedEncodingException e) {
  51.  
     
  52.  
    }
  53.  
    }
  54.  
    matcher.appendTail(sb);
  55.  
    return sb.toString();
  56.  
    }
  57.  
     
  58.  
     
  59.  
    }

      利:减少服务器端转换编码带来的风险和压力
      弊:客户端需要根据不同的设备系统自行做编码转换

注意: 这两种方案我都自己试验过,如果服务器时自己的话,我觉得采取第一种方案挺方便的,也不需要编码什么的,转来转去。如果数据时存储在他人服务器上的(比如阿里云),但是别人的服务器不允许存储emoji,那么我觉得采取第二种方案会好很多.

  参考博客来源:https://blog.csdn.net/u010839779/article/details/45559291

  参考博客来源:https://www.cnblogs.com/shihaiming/p/5833244.html

 
posted @ 2021-08-10 14:02  万事俱备就差个程序员  阅读(323)  评论(0编辑  收藏  举报

http://xiangai.taobao.com
http://shop148612228.taobao.com
如果您觉得对您有帮助.领个红包吧.谢谢.
支付宝红包
微信打赏 支付宝打赏