如何确定字符串是否包含无效的编码字符
使用场景
我们已经实现了一个Web服务,我们的Web前端开发人员在内部使用(通过php API)来显示产品数据。在网站上,用户输入一些东西(即查询字符串)。在内部,网站通过 api 调用服务。
注意:我们使用 restlet,而不是 tomcat
原始问题
Firefox 3.0.10 似乎遵循浏览器中选定的编码,并根据所选的编码对 url 进行编码。这确实会导致 ISO-8859-1 和 UTF-8 的查询字符串不同。
我们的网站转发来自用户的输入,并且不会转换它(它应该转换),因此它可以通过api调用服务,使用包含德语元音变音符的查询字符串调用Web服务。
即,对于查询部分,如下所示
...v=abcädef
如果选择了“ISO-8859-1”,则发送的查询部分如下所示
...v=abc%E4def
但如果选择了“UTF-8”,则发送的查询部分看起来像
...v=abc%C3%A4def
期望的解决方案
当我们控制服务时,因为我们已经实现了它,所以我们要在服务器端检查调用是否包含非utf-8字符,如果是这样,请使用4xx http状态进行响应
当前解决方案详情
检查每个字符 ( == string.substring(i,i+1) )
- if character.getBytes()[0] 等于 63 表示 '?'
- 如果 Character.getType(character.charAt(0)) 返回 OTHER_SYMBOL
法典
protected List< String > getNonUnicodeCharacters( String s ) {
final List< String > result = new ArrayList< String >();
for ( int i = 0 , n = s.length() ; i < n ; i++ ) {
final String character = s.substring( i , i + 1 );
final boolean isOtherSymbol =
( int ) Character.OTHER_SYMBOL
== Character.getType( character.charAt( 0 ) );
final boolean isNonUnicode = isOtherSymbol
&& character.getBytes()[ 0 ] == ( byte ) 63;
if ( isNonUnicode )
result.add( character );
}
return result;
}
问题
这会捕获所有无效(非 utf 编码)字符吗?你们中是否有人有更好(更简单)的解决方案?
注意:我用下面的代码检查了URLDecoder
final String[] test = new String[]{
"v=abc%E4def",
"v=abc%C3%A4def"
};
for ( int i = 0 , n = test.length ; i < n ; i++ ) {
System.out.println( java.net.URLDecoder.decode(test[i],"UTF-8") );
System.out.println( java.net.URLDecoder.decode(test[i],"ISO-8859-1") );
}
这打印:
v=abc?def
v=abcädef
v=abcädef
v=abcädef
它不会抛出一个非法的争论异常叹息