82 lines
2.6 KiB
Java
82 lines
2.6 KiB
Java
|
|
package cn.keking.utils;
|
|||
|
|
import java.util.BitSet;
|
|||
|
|
|
|||
|
|
|
|||
|
|
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');
|
|||
|
|
}
|
|||
|
|
}
|