Как определить, содержит ли строка недопустимые закодированные символы

Сценарий использования

Мы внедрили веб-сервис, который наши разработчики веб-интерфейса используют (через 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вздох

Ответы на вопрос(10)

Ваш ответ на вопрос