//记得要先 判断昵称是否有特殊符号,或者表情, 转化成数据库可以存储的值
String nick = UrlEncoderUtils.transforStr(nickName);
String nick = URLEncoder.encode(nick,"utf-8");
具体的封装类
public class UrlEncoderUtils {
private static BitSet dontNeedEncoding;
static {
dontNeedEncoding = new BitSet(256);
int i;
for (i = 'a'; i <= 'z'; i++) {
dontNeedEncoding.set(i);
}
for (i = 'A'; i <= 'Z'; i++) {
dontNeedEncoding.set(i);
}
for (i = '0'; i <= '9'; i++) {
dontNeedEncoding.set(i);
}
dontNeedEncoding.set('+');
/**
* 这里会有误差,比如输入一个字符串 123+456,它到底是原文就是123+456还是123 456做了urlEncode后的内容呢?<br>
* 其实问题是一样的,比如遇到123%2B456,它到底是原文即使如此,还是123+456 urlEncode后的呢? <br>
* 在这里,我认为只要符合urlEncode规范的,就当作已经urlEncode过了<br>
* 毕竟这个方法的初衷就是判断string是否urlEncode过<br>
*/
dontNeedEncoding.set('-');
dontNeedEncoding.set('_');
dontNeedEncoding.set('.');
dontNeedEncoding.set('*');
}
/**
* 判断str是否urlEncoder.encode过<br>
* 经常遇到这样的情况,拿到一个URL,但是搞不清楚到底要不要encode.<Br>
* 不做encode吧,担心出错,做encode吧,又怕重复了<Br>
*
* @param str
* @return
*/
public static boolean hasUrlEncoded(String str) {
/**
* 支持JAVA的URLEncoder.encode出来的string做判断。 即: 将' '转成'+' <br>
* 0-9a-zA-Z保留 <br>
* '-','_','.','*'保留 <br>
* 其他字符转成%XX的格式,X是16进制的大写字符,范围是[0-9A-F]
*/
boolean needEncode = false;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (dontNeedEncoding.get((int) c)) {
continue;
}
if (c == '%' && (i + 2) < str.length()) {
// 判断是否符合urlEncode规范
char c1 = str.charAt(++i);
char c2 = str.charAt(++i);
if (isDigit16Char(c1) && isDigit16Char(c2)) {
continue;
}
}
// 其他字符,肯定需要urlEncode
needEncode = true;
break;
}
return !needEncode;
}
/**
* 判断c是否是16进制的字符
*
* @param c
* @return
*/
private static boolean isDigit16Char(char c) {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
}
/**
* 判断昵称是否有特殊符号,或者表情, 转化成数据库可以存储的值
*
* @param str
* @return
*/
public static String transforStr(String str) {
String para = null;
//先判断是否为null
if(StringUtil.hasValue(str)) {
//判断昵称是否有特殊符号,或者表情
boolean result = EmojiUtil.containsEmoji(str);
try {
if(result) { //是
//转码成中文
para = URLEncoder.encode(str,"utf-8");
}
}catch (Exception e) {
e.printStackTrace();
}
}else {
para = str;
}
return para;
}
/**
* 判断昵称是否有已经被URLEncoder.encode转化过, 是的话,返回原码返回
*
* @param str
* @return
*/
public static String transforCN(String str) {
String para = null;
//先判断是否为null
if(StringUtil.hasValue(str)) {
//判断昵称是否有特殊符号,或者表情
boolean result = UrlEncoderUtils.hasUrlEncoded(str);
try {
if(result) { //是
//转码成中文
para = URLDecoder.decode(str,"utf-8");
}
}catch (Exception e) {
e.printStackTrace();
}
}else {
para = str;
}
return para;
}
}
还有一个判断方法
public class EmojiUtil{
/**
* 检测是否有emoji字符
* @param source
* @return 一旦含有就抛出
*/
public static boolean containsEmoji(String source) {
if (StringUtils.isBlank(source)) {
return false;
}
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (isEmojiCharacter(codePoint)) {
//do nothing,判断到了这里表明,确认有表情字符
return true;
}
}
return false;
}
private static boolean isEmojiCharacter(char codePoint) {
return (0x0080<=codePoint&&codePoint<=0x02AF)||
(0x0300<=codePoint&&codePoint<=0x03FF)||
(0x0600<=codePoint&&codePoint<=0x06FF)||
(0x0C00<=codePoint&&codePoint<=0x0C7F)||
(0x1DC0<=codePoint&&codePoint<=0x1DFF)||
(0x1E00<=codePoint&&codePoint<=0x1EFF)||
(0x2000<=codePoint&&codePoint<=0x209F)||
(0x20D0<=codePoint&&codePoint<=0x214F)||
(0x2190<=codePoint&&codePoint<=0x23FF)||
(0x2460<=codePoint&&codePoint<=0x25FF)||
(0x2600<=codePoint&&codePoint<=0x27EF)||
(0x2900<=codePoint&&codePoint<=0x29FF)||
(0x2B00<=codePoint&&codePoint<=0x2BFF)||
(0x2C60<=codePoint&&codePoint<=0x2C7F)||
(0x2E00<=codePoint&&codePoint<=0x2E7F)||
(0xA490<=codePoint&&codePoint<=0xA4CF)||
(0xE000<=codePoint&&codePoint<=0xF8FF)||
(0xFE00<=codePoint&&codePoint<=0xFE0F)||
(0xFE30<=codePoint&&codePoint<=0xFE4F)||
(0x1F000<=codePoint&&codePoint<=0x1F02F)||
(0x1F0A0<=codePoint&&codePoint<=0x1F0FF)||
(0x1F100<=codePoint&&codePoint<=0x1F64F)||
(0x1F680<=codePoint&&codePoint<=0x1F6FF)||
(0x1F910<=codePoint&&codePoint<=0x1F96B)||
(0x1F980<=codePoint&&codePoint<=0x1F9E0);
}
/**
* 过滤emoji 或者 其他非文字类型的字符
* @param source
* @return
*/
public static String filterEmoji(String source) {
source = source.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "*");
if (!containsEmoji(source)) {
return source;//如果不包含,直接返回
}
//到这里铁定包含
StringBuilder buf = null;
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (isEmojiCharacter(codePoint)) {
if (buf == null) {
buf = new StringBuilder(source.length());
}
buf.append(codePoint);
} else {
buf.append("*");
}
}
if (buf == null) {
return source;//如果没有找到 emoji表情,则返回源字符串
} else {
if (buf.length() == len) {//这里的意义在于尽可能少的toString,因为会重新生成字符串
buf = null;
return source;
} else {
return buf.toString();
}
}
}
}
之后就是正常的持久化即可
当然还有更好的办法
Mybatis+MySql 保存emoji表情