Как определить, содержит ли строка недопустимые закодированные символы
Сценарий использования
Мы внедрили веб-сервис, который наши разработчики веб-интерфейса используют (через php api) для отображения данных о продукте. На веб-сайте пользователь вводит что-то (то есть строку запроса). Внутренне сайт совершает звонок в сервис через API.
Примечание: мы используем restlet, а не tomcat
Оригинальная проблема
Firefox 3.0.10, похоже, учитывает выбранную кодировку в браузере и кодирует URL в соответствии с выбранной кодировкой. Это приводит к различным строкам запроса для ISO-8859-1 и UTF-8.
Наш веб-сайт пересылает ввод от пользователя и не преобразует его (что и должно), поэтому он может сделать вызов службе через API, вызывающий веб-сервис, используя строку запроса, содержащую умлауты на немецком языке.
То есть для части запроса, выглядящей как
...v=abcädef
если выбран «ISO-8859-1», отправленная часть запроса выглядит так
...v=abc%E4def
но если выбран «UTF-8», часть отправленного запроса выглядит так
...v=abc%C3%A4def
Желаемое решение
Поскольку мы контролируем сервис, потому что мы внедрили его, мы хотим проверитьсерверная сторона Если вызов содержит не UTF-8 символов, если это так, ответьте HTTP-статусом 4xx
Текущее решение в деталях
Проверьте для каждого символа (== string.substring (i, i + 1))
если character.getBytes () [0] равно 63 для '?'if 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
и это делаетне бросить IllegalArgumentExceptionвздох