在做微信公众号开发时碰到了获取微信基本信息的需求,但是在像数据库保存用户昵称的时候出错了,

出错原因是微信用户的昵称中包含emoji等特殊符号,表情图片,

mysql数据库使用的是utf8,最大存储3个字节,而emoji等以4个字节进行的保存,所以保存不了

处理方法:

1:修改数据库编码由utf8升级为utf8mb4,utf8mb4是utf8的超级,包含全部unicode编码;该方法没有具体操作;

2:进行过滤,对获取到的用户昵称进行编码过滤,对emoji等替换为“”空;但是该方法在碰到iso上的一些emoji就失败了。在下方增加了一些处理过滤方法;

该过滤方法找自于网上
/**
* 检测是否有emoji字符
* @param source
* @return 一旦含有就抛出
*/
public static boolean containsEmoji(String source) {
if (StringUtils.isBlank(source)) {
return false;
} int len = source.length(); for (int i = ; i < len; i++) {
char codePoint = source.charAt(i); if (isEmojiCharacter(codePoint)) {
//do nothing,判断到了这里表明,确认有表情字符
return true;
}
} return false;
} private static boolean isEmojiCharacter(char codePoint) {
return (codePoint == 0x0) ||
(codePoint == 0x9) ||
(codePoint == 0xA) ||
(codePoint == 0xD) ||
((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
} /**
* 过滤emoji 或者 其他非文字类型的字符
* @param source
* @return
*/
public static String filterEmoji(String source) { if (!containsEmoji(source)) {
       //特殊处理
       source = filterSpecialCharacter(source);
return source;//如果不包含,直接返回
}
//到这里铁定包含
StringBuilder buf = null; int len = source.length(); for (int i = ; i < len; i++) {
char codePoint = source.charAt(i); if (isEmojiCharacter(codePoint)) {
if (buf == null) {
buf = new StringBuilder(source.length());
} buf.append(codePoint);
} else {
}
} if (buf == null) {
return source;//如果没有找到 emoji表情,则返回源字符串
} else {
if (buf.length() == len) {//这里的意义在于尽可能少的toString,因为会重新生成字符串
buf = null;
return source;
} else {
return buf.toString();
}
} }
 /**
* 判断特殊字符,替换成空格
*
* @param source
* @return 过滤后的字符串
*/
public static String filterSpecialCharacter(String source) {
if(StringUtils.isNotBlank(source)){
Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",Pattern . UNICODE_CASE | Pattern . CASE_INSENSITIVE);
Matcher emojiMatcher = emoji.matcher(source);
if (emojiMatcher.find()) {
return source.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "");
}else{
return source;
}
}else{
return source;
}
}

方法3:

    /**
* 过滤掉超过3个字节的UTF8字符
* @param text
* @return
* @throws UnsupportedEncodingException
*/
public static String filterOffUtf8Mb4(String text) throws UnsupportedEncodingException {
byte[] bytes = text.getBytes("utf-8");
ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
int i = ;
while (i < bytes.length) {
short b = bytes[i];
if (b > ) {
buffer.put(bytes[i++]);
continue;
} b += ; // 去掉符号位 if (((b >> ) ^ 0x6) == ) {
buffer.put(bytes, i, );
i += ;
} else if (((b >> ) ^ 0xE) == ) {
buffer.put(bytes, i, );
i += ;
} else if (((b >> ) ^ 0x1E) == ) {
i += ;
} else if (((b >> ) ^ 0x3E) == ) {
i += ;
} else if (((b >> ) ^ 0x7E) == ) {
i += ;
} else {
buffer.put(bytes[i++]);
}
}
buffer.flip();
return new String(buffer.array(), "utf-8");
}

方法4:进行编码转换保存

将需要处理的字符串进行编码转换,存储到数据库

/**
* 字符串转换ascii
*/
public static String string2Unicode(String string) {
StringBuffer unicode = new StringBuffer();
for (int i = ; i < string.length(); i++) {
// 取出每一个字符
char c = string.charAt(i);
// 转换为unicode
unicode.append("\\u" + Integer.toHexString(c));
}
return unicode.toString();
}
/**
* ascii 转字符串
*/
public static String unicode2String(String unicode) {
StringBuffer string = new StringBuffer();
String[] hex = unicode.split("\\\\u");
for (int i = ; i < hex.length; i++) {
// 转换出每一个代码点
int data = Integer.parseInt(hex[i], );
// 追加成string
string.append((char) data);
}
return string.toString();
}

在页面获取的时候进行处理

//js ascii转string
function ascii2native(){
//var character=document.getElementById("nikeunicode").value.split("\\u");
var x=document.getElementsByClassName("nikeunicode"); var k;
for (k = ; k < x.length; k++) {
console.log(x[k].innerHTML);
var character=x[k].innerHTML.split("\\u");
var native=character[];
console.log(native);
for(var i=;i<character.length;i++){
var code=character[i];
native+=String.fromCharCode(parseInt("0x"+code.substring(,)));
if(code.length>){
native+=code.substring(,code.length);
}
}
x[k].innerHTML=native;
} //document.getElementById("nikeunicode").value=native1;
}

页面处理过的效果

上文中的方法在android输入法自带的emoji下,没有起到效果,在上文方法2的if (isEmojiCharacter(codePoint)) 处加入下列判断

private static boolean isChinese(char c) {
Character.UnicodeScript sc = Character.UnicodeScript.of(c);
if (sc == Character.UnicodeScript.HAN) {
return true;
}
return false;
} public static boolean isPunctuation(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if ( // punctuation, spacing, and formatting characters
ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
// symbols and punctuation in the unified Chinese, Japanese and Korean script
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
// fullwidth character or a halfwidth character
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
// vertical glyph variants for east Asian compatibility
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
// vertical punctuation for compatibility characters with the Chinese Standard GB 18030
|| ub == Character.UnicodeBlock.VERTICAL_FORMS
// ascii
|| ub == Character.UnicodeBlock.BASIC_LATIN
) {
return true;
} else {
return false;
}
} private static Boolean isUserDefined(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.NUMBER_FORMS
|| ub == Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS
|| ub == Character.UnicodeBlock.LETTERLIKE_SYMBOLS
|| c == '\ufeff'
|| c == '\u00a0'
)
return true;
return false;
} public static boolean isMessy(String str) {
float chlength = ;
float count = ;
for(int i = ; i < str.length(); i++) {
char c = str.charAt(i);
if(isPunctuation(c) || isUserDefined(c))
continue;
else {
if(!isChinese(c)) {
count = count + ;
}
chlength ++;
}
}
float result = count / chlength;
if(result > 0.3){
return true;
}else{
return false;
} }

emoji处理方法的更多相关文章

  1. emoji处理方法汇总

    emoji资料 今天研究了emoji,挺有意思,资料挺多,摘要一些信息给大家分享,也算是自己记录学习. emoji介绍 Emoji (絵文字,词义来自日语えもじ,e-moji,moji在日语中的含义是 ...

  2. 前端如何处理emoji表情

    这段时间在做移动端的开发, 有一个功能就是发表评论,其实这个功能本身是比较简单的, 但是在提测是的时候QA给哦提了一个bug,说输入手机自带的emoji表情发送失败了.我就奇怪了,emoji表情也是文 ...

  3. 微信昵称的emoji的尝试性解决方案

    概述 之前分享过前端页面使用emoji,讨论了前端页面使用emoji的方法,但是微信昵称中的emoji怎么获取和显示呢?我查找了一些资料,把心得记录下来,供以后开发时参考,相信对其他人也有用. 转码问 ...

  4. Java转义emoji等特殊符号

    写在前面 网上找了很多转emoji等方法,大多有两种方法 更改数据库编码格式为utf8mb4 过滤字符串中的emoji 都不是很优雅 更改数据库编码,势必影响其他数据库 过滤emoj效率比较低 处理E ...

  5. Android Emoji兼容包使用详解

    Emoji兼容性 我们经常会遇到这样的问题: 给朋友发的emoji表情, 在自己手机上展示是正常的, 但是到朋友手机上, 却没有展示出来, 或者展示出来了, 但是也跟自己手机上展示的不一样. 所以,  ...

  6. filter 过滤emoji

    拦截器 public class EmojiFilter implements Filter { private FilterConfig filterConfig; public void init ...

  7. 宅在家学不进去吗?试试这些 GitHub 上简单易学的游戏项目吧

    作者:HelloGitHub-小鱼干 这是本人宅在家里的第 4 周,代码不想看,技术文章不想读,都不能愉快学习了我还怎么当一个优秀的需求消化师呢?有没有什么轻松地方法来学习技术呢?想起了小时候金山打字 ...

  8. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  9. Django1.10+Mysql 5.7存储emoji表情,报Incorrect string value: '\\xF0\\x9F\\x90\\xA8' for column 'signature' at row 1的解决方法

    问题: 在做webapp项目的时候,用户提交emoji数据,控制台报错:Incorrect string value: '\\xF0\\x9F\\x90\\xA8' for column 'signa ...

随机推荐

  1. 接口上传base64编码图片

    package com.*.util; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io. ...

  2. Web核心之Request对象

    HTTP协议中Request请求部分格式 //请求行(这种是POST类型的请求) POST /HttpServleLogin.html HTTP/1.1 //请求头(User-Agent里有Firef ...

  3. SpringBoot JSON文件读取

    @Componentpublic class StepExecutor implements Runnable { @Value("classpath:menu.json") pr ...

  4. Ext js-01 -helloworld

    一.下载ext: 登陆这个网址  https://www.sencha.com/products/evaluate/ 下载下来解压后如下:安装cmd程序 二.开始helloworld 新建一个idea ...

  5. linux0.11源码内核——系统调用,int80的实现细节

    linux0.11添加系统调用的步骤 假设添加一个系统调用foo() 1.修改include/linux/sys.h 添加声明 extern int foo(); 同时在sys_call_table数 ...

  6. 高并发大流量专题---11、Web服务器的负载均衡

    高并发大流量专题---11.Web服务器的负载均衡 一.总结 一句话总结: 推荐使用nginx七层(应用层)负载均衡的实现:配置那是相当的简单 http{ upstream cluster{ serv ...

  7. Majordomo Info VGER.KERNEL.ORG

    This is VGER.KERNEL.ORG Majordomo Info The mission of vger.kernel.org is to provide email list servi ...

  8. jenkins-参数化构建插件:Choice Parameter

    参考: 谢谢大佬的总结: https://www.cnblogs.com/zhaojingyu/p/9862371.html 使用方式 step1: 添加参数,选择Choice Parameter,并 ...

  9. MySQL开启SSL认证,以及简单优化

    1.1 MySQL开启SSL认证 #生成一个 CA 私钥 [root@db01 ssl]# openssl genrsa 2048 > ca-key.pem Generating RSA pri ...

  10. c# 自定义控件之 ComboBox

    winform 自带的 combobox 无法支持根据输入文本匹配列表中的项目,需要使用自定义控件. public class MyCombobox : ComboBox { //初始化数据项 pri ...