Как проверить кодировку строки в Java?
В моем приложении я получаю информацию о пользователе из LDAP, и иногда полное имя пользователя входит в неправильную кодировку. Например:
ТеÑÑ61 ТеÑÑовиÑ61
Он также может быть на английском или русском языке и отображен правильно. Если имя пользователя изменяется, оно обновляется в базе данных. Даже если я изменю значение в db, оно не решит проблему.
Я могу исправить его до сохранения, сделав это
new String(incorrect.getBytes("ISO-8859-1"), "UTF-8");
Однако, если я буду использовать его для строки, содержащей символы на русском языке (например, "Тест61 Тестович61" ), я получаю что-то вроде этого "???? 61???????? 61".
Можете ли вы предложить что-то, что может определить кодировку строки?
Ответы
Ответ 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.