• java.sql.SQLException: Incorrect string value: 'xF0x9Fx92x94' for column '*****' at row 1


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

    1.  
      Caused by: java.sql.SQLException: Incorrect string value: 'xF0x9Fx98x84' 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

     
  • 相关阅读:
    那些陌生的C++关键字
    从实现装饰者模式中思考C++指针和引用的选择
    单例模式(Singleton)
    命令模式(Command)
    抽象工厂模式(Abstract Factory)
    《Effective C++》读书摘要
    桥接模式(Bridge)
    适配器模式(Adapter)
    设计模式学习心得
    黑客常用WinAPI函数整理
  • 原文地址:https://www.cnblogs.com/suizhikuo/p/15123511.html
Copyright © 2020-2023  润新知