博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决文字和表情存储到msql数据库出现异常问题
阅读量:6947 次
发布时间:2019-06-27

本文共 9475 字,大约阅读时间需要 31 分钟。

hot3.png

异常:

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\xA4\x97 \xF0...' for column 'name' at row 1

    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:45)
    at com.sun.proxy.$Proxy21.execute(Unknown Source)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:23)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:51)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:29)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:74)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:44)
    at com.sun.proxy.$Proxy20.update(Unknown Source)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:118)
    ... 61 more

异常原因:

数据库一般设置的编码格式是utf-8格式,而utf-8只包含3个字节编码,然而现在出现了4个字节编码格式,导致程序识别失败。

两种解决方法

1)把数据库编码格式设置成utf8mb4格式,其对应数据表也设置成其utf8mb4编码格式

2)直接过滤掉其多余的编码格式字节。使用其过滤工具类进行过滤,从而达到目的

public class UTF8Utils {    public static Map
hexMap = new HashMap
(); public static Map
byteMap = new HashMap
(); static { hexMap.put("0", 2); hexMap.put("1", 2); hexMap.put("2", 2); hexMap.put("3", 2); hexMap.put("4", 2); hexMap.put("5", 2); hexMap.put("6", 2); hexMap.put("7", 2); hexMap.put("c", 4); hexMap.put("d", 4); hexMap.put("e", 6); hexMap.put("f", 8); byteMap.put("0", 1); byteMap.put("1", 1); byteMap.put("2", 1); byteMap.put("3", 1); byteMap.put("4", 1); byteMap.put("5", 1); byteMap.put("6", 1); byteMap.put("7", 1); byteMap.put("c", 2); byteMap.put("d", 2); byteMap.put("e", 3); byteMap.put("f", 4); } /** * 是否包含4字节UTF-8编码的字符(先转换16进制再判断) * @param s 字符串 * @return 是否包含4字节UTF-8编码的字符 */ public static boolean contains4BytesChar(String s) { if (s == null || s.trim().length() == 0) { return false; } String hex = UTF8Utils.bytesToHex(s.getBytes());// System.out.println("full hex : " + hex); String firstChar = null; while (hex != null && hex.length() > 1) { firstChar = hex.substring(0, 1);// System.out.println("firstChar : " + firstChar); if ("f".equals(firstChar)) {// System.out.println("it is f start, it is 4 bytes, return."); return true; } if (hexMap.get(firstChar) == null) {// System.out.println("it is f start, it is 4 bytes, return."); // todo, throw exception for this case return false; } hex = hex.substring(hexMap.get(firstChar), hex.length());// System.out.println("remain hex : " + hex); } return false; } /** * 是否包含4字节UTF-8编码的字符 * @param s 字符串 * @return 是否包含4字节UTF-8编码的字符 */ public static boolean contains4BytesChar2(String s) { if (s == null || s.trim().length() == 0) { return false; } byte[] bytes = s.getBytes(); if (bytes == null || bytes.length == 0) { return false; } int index = 0; byte b; String hex = null; String firstChar = null; int step; while (index <= bytes.length - 1) {// System.out.println("while loop, index : " + index); b = bytes[index]; hex = byteToHex(b); if (hex == null || hex.length() < 2) {// System.out.println("fail to check whether contains 4 bytes char(1 byte hex char too short), default return false."); // todo, throw exception for this case return false; } firstChar = hex.substring(0, 1); if (firstChar.equals("f")) { return true; } if (byteMap.get(firstChar) == null) {// System.out.println("fail to check whether contains 4 bytes char(no firstchar mapping), default return false."); // todo, throw exception for this case return false; } step = byteMap.get(firstChar);// System.out.println("while loop, index : " + index + ", step : " + step); index = index + step; } return false; } /** * 去除4字节UTF-8编码的字符 * @param s 字符串 * @return 已去除4字节UTF-8编码的字符 */ public static byte[] remove4BytesUTF8Char(String s) { byte[] bytes = s.getBytes(); byte[] removedBytes = new byte[bytes.length]; int index = 0; String hex = null; String firstChar = null; for (int i = 0; i < bytes.length; ) { hex = UTF8Utils.byteToHex(bytes[i]); if (hex == null || hex.length() < 2) {// System.out.println("fail to check whether contains 4 bytes char(1 byte hex char too short), default return false."); // todo, throw exception for this case return null; } firstChar = hex.substring(0, 1); if (byteMap.get(firstChar) == null) {// System.out.println("fail to check whether contains 4 bytes char(no firstchar mapping), default return false."); // todo, throw exception for this case return null; } if (firstChar.equals("f")) { for (int j = 0; j < byteMap.get(firstChar); j++) { i++; } continue; } for (int j = 0; j < byteMap.get(firstChar); j++) { removedBytes[index++] = bytes[i++]; } } return Arrays.copyOfRange(removedBytes, 0, index); } /** * 将字符串的16进制转换为HEX,并按每个字符的16进制分隔格式化 * @param s 字符串 */ public static String splitForReading(String s) { if (s == null || s.trim().length() == 0) { return ""; } String hex = UTF8Utils.bytesToHex(s.getBytes());// System.out.println("full hex : " + hex); if (hex == null || hex.length() == 0) {// System.out.println("fail to translate the bytes to hex."); // todo, throw exception for this case return ""; } StringBuilder sb = new StringBuilder(); int index = 0; String firstChar = null; String splittedString = null; while (index < hex.length()) { firstChar = hex.substring(index, index + 1); if (hexMap.get(firstChar) == null) {// System.out.println("fail to check whether contains 4 bytes char(no firstchar mapping), default return false."); // todo, throw exception for this case return ""; } splittedString = hex.substring(index, index + hexMap.get(firstChar)); sb.append(splittedString).append(" "); index = index + hexMap.get(firstChar); }// System.out.println("formated sb : " + sb); return sb.toString(); } /** * 字节数组转十六进制 * @param bytes 字节数组 * @return 十六进制 */ public static String bytesToHex(byte[] bytes) { if (bytes == null || bytes.length == 0) { return null; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { int r = bytes[i] & 0xFF; String hexResult = Integer.toHexString(r); if (hexResult.length() < 2) { sb.append(0); // 前补0 } sb.append(hexResult); } return sb.toString(); } /** * 字节转十六进制 * @param b 字节 * @return 十六进制 */ public static String byteToHex(byte b) { int r = b & 0xFF;//获得低8位 String hexResult = Integer.toHexString(r); StringBuilder sb = new StringBuilder(); if (hexResult.length() < 2) { sb.append(0); // 前补0 } sb.append(hexResult); return sb.toString(); }}

转载于:https://my.oschina.net/u/2251646/blog/1030987

你可能感兴趣的文章
实战Kafka ACL机制
查看>>
云监控服务使用教程
查看>>
“旧城改造”的背后——银泰新零售阿里云解决方案(上)
查看>>
java B2B2C源码电子商务平台 -SpringCloud服务相互调用RestTemplate
查看>>
java B2B2C Springcloud电子商务平台源码-zuul 过滤器机制
查看>>
分布式消息系统:Kafka
查看>>
我的友情链接
查看>>
H3C防火墙路由器做回流
查看>>
Tableau10.5视频课程之常见图形制作
查看>>
Kettle5.4实战项目培训课程
查看>>
获取局域网里一个MAC地址对于的IP地址
查看>>
让phpmailer支持中文名称的附件和邮件标题中文乱码(转)
查看>>
JavaScript强化教程——JavaScript Math(算数) 对象
查看>>
CentOS7部署Kubernetes集群
查看>>
struts2中使用DMI(动态调用方法)方式配置action
查看>>
使用hyperpacer实现AWR报告的同步收集
查看>>
关于os.popen你可能不知道的
查看>>
redhat5.3恢复***
查看>>
linux 下mysql的乱码问题
查看>>
门面模式/Facade
查看>>