0.背景
一般在使用接口传输数据时通常会使用两种数据交换格式:JSON、XML。json通常用于前后端交互,xml可通过命名空间和规范check tag的层次关系,都可以很好地与对象互相转换。但是由于有的字符在格式上被用了,字段内容如果包含这些特殊字符需要进行转义!
1.XML特殊字符
xml的特殊字符 包括< > & "
标签内容特殊 | 转义后 |
< | < |
> | > |
& | & |
" | " |
/**
* 过滤要输出到xml的字符串,将<,>,&,"进行转义输出
*
* @param input
* @return
*/
public static String filterXMLString(String input) {
if (input == null) {
return EMPTY_STRING;
}
int length = input.length();
StringBuilder result = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = input.charAt(i);
switch (c) {
case '<': {
result.append("<");
break;
}
case '>': {
result.append(">");
break;
}
case '\"': {
result.append(""");
break;
}
case '&': {
result.append("&");
break;
}
default: {
result.append(c);
}
}
}
return result.toString();
}
@Test
public void testXMLEscape(){
String str = "Posco P&S Tower < > & \"" ;
System.out.println(StringUtil.filterXMLString(str)); //Posco P&S Tower < > & "
}
1.Json特殊字符
json 只有有69个:*+-./@_0-9a-zA-Z 不需要转码 ,算术加减乘除 4个,.小数点、@、 _下划线、数字10个、大小写26个字母 26*2
4+1+1+1+10+26*2=69
类型 | 个数 |
数字0-9 | 10 |
小数点. | 1 |
加减乘除+-*/ | 4 |
大小写字母 a-z A-Z | 52 |
@ | 1 |
_ | 1 |
总计 | 69 |
其余的字符都需要进行转码,如果在拉丁字符,就直接转ASCII编码%hex[ch];
如果非拉丁,则转unicode编码%uhex[(ch >>> 8)]hex[(0x00FF & ch)
/**
* 编码,模拟js的escape函数.<br>
* escape不编码字符有69个:*+-./@_0-9a-zA-Z
*
* @param s
* 字符串
* @return 转义后的字符串或者null
*/
public static String escape(String s) {
if (s == null) {
return null;
}
StringBuffer sbuf = new StringBuffer();
int len = s.length();
for (int i = 0; i < len; i++) {
int ch = s.charAt(i);
if ('A' <= ch && ch <= 'Z') {
sbuf.append((char) ch);
} else if ('a' <= ch && ch <= 'z') {
sbuf.append((char) ch);
} else if ('0' <= ch && ch <= '9') {
sbuf.append((char) ch);
} else if (ch == '*' || ch == '+' || ch == '-' || ch == '/' || ch == '_' || ch == '.'
|| ch == '@') {
sbuf.append((char) ch);
} else if (ch <= 0x007F) {
sbuf.append('%');
sbuf.append(hex[ch]);
} else {
sbuf.append('%');
sbuf.append('u');
sbuf.append(hex[(ch >>> 8)]);
sbuf.append(hex[(0x00FF & ch)]);
}
}
return sbuf.toString();
}