Подтвердить что ты не робот

Как проверить кодировку строки в Java?

В моем приложении я получаю информацию о пользователе из LDAP, и иногда полное имя пользователя входит в неправильную кодировку. Например:

ТеÑÑ61 ТеÑÑовиÑ61

Он также может быть на английском или русском языке и отображен правильно. Если имя пользователя изменяется, оно обновляется в базе данных. Даже если я изменю значение в db, оно не решит проблему.

Я могу исправить его до сохранения, сделав это

new String(incorrect.getBytes("ISO-8859-1"), "UTF-8");

Однако, если я буду использовать его для строки, содержащей символы на русском языке (например, "Тест61 Тестович61" ), я получаю что-то вроде этого "???? 61???????? 61".

Можете ли вы предложить что-то, что может определить кодировку строки?

4b9b3361

Ответ 1

Строки в java, AFAIK, не сохраняют исходную кодировку - они всегда хранятся внутри какой-либо формы в Юникоде. Вы хотите обнаружить кодировку исходного потока/байтов - вот почему я думаю, что ваш вызов String.toBytes() слишком поздний.

В идеале, если вы можете получить поток ввода, из которого вы читаете, вы можете запустить его через что-то вроде этого: http://code.google.com/p/juniversalchardet/

Есть много других детекторов кодировки, а также

Ответ 2

Ваша база данных LDAP настроена неправильно. Приложение, помещающее данные в него, должно преобразовать в известную кодировку набора символов, в вашем случае, скорее всего, UTF_16. Выберите стандарт. Все методы обнаружения кодировки - догадки.

Приложение, записывающее значение, является единственным, которое знает окончательно, какую кодировку оно использует, и может правильно преобразовать в другую кодировку, такую ​​как UTF_16.

Ответ 3

Я рекомендую Apache.tika CharsetDetector, очень дружелюбный и сильный.

CharsetDetector detector = new CharsetDetector();
detector.setText(yourStr.getBytes());
detector.detect();  // <- return the result, you can check by .getName() method

Кроме того, вы можете преобразовать любую кодированную строку в нужную, возьмите utf-8 в качестве примера:

detector.getString(yourStr.getBytes(), "utf-8");

Ответ 4

В своем веб-приложении вы можете объявить фильтр кодировки, который гарантирует, что вы получите данные в правильной кодировке.

<filter>
    <description>Explicitly set the encoding of the page to UTF-8</description>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

A spring предоставленный фильтр гарантирует, что контроллеры/сервлеты получат параметры в UTF-8.

Ответ 5

У меня была та же проблема. Tika слишком велик, и juniversalchartet не обнаруживает ISO-8859-1. Итак, я сделал сам и теперь хорошо работаю в производстве:

public String convert(String value, String fromEncoding, String toEncoding) {
  return new String(value.getBytes(fromEncoding), toEncoding);
}

public String charset(String value, String charsets[]) {
  String probe = StandardCharsets.UTF_8.name();
  for(String c : charsets) {
    Charset charset = Charset.forName(c);
    if(charset != null) {
      if(value.equals(convert(convert(value, charset.name(), probe), probe, charset.name()))) {
        return c;
      }
    }
  }
  return StandardCharsets.UTF_8.name();
}

Полное описание здесь: Обнаружение кодировки в строках Java.