Проблема : иногда мы получаем ссылки / фразы с недопустимой (для нас) кодировкой.
Примеры и мое первое решение ниже
Описание : Я должен исправить недопустимые закодированные строки в одной части приложения. Иногда это слово или фраза, а иногда и URL. Когда это URL, я хотел бы изменить только неправильно закодированные символы. Если я декодирую с ISO и кодирую в UTF-8, специальные символы URL также кодируются (/:? = &). Я кодировал решение, которое отлично работает для моих дел, но те хеши, которые вы увидите ниже, плохо пахнут для меня.
У вас была похожая проблема или вы знаете библиотеку, которая позволяет декодировать фразу, кроме некоторых символов? Примерно так:
decode(String value, char[] ignored)
Я также хотел бы разбить URL на части и исправить только путь и запрос, но было бы еще больше беспорядка при их разборе и т. Д. c ..
TLDR : декодировать URL-адрес в кодировке ISO-8858-1 и кодировать его в UTF-8. Не прикасайтесь к указанным URL-адресам c символов (/ ? = : &
)
Примеры ввода / вывода :
// wrong input
"http://some.url/xxx/a/%e4t%fcr%E4/b/%e4t%fcr%E4"
"t%E9l%E9phone"
// good output
"http://some.url/xxx/a/%C3%A4t%C3%BCr%C3%A4/b/%C3%A4t%C3%BCr%C3%A4"
"t%C3%A9l%C3%A9phone"
// very wrong output
"http%3A%2F%2Fsome.url%2Fxxx%2Fa%2F%C3%A4t%C3%BCr%C3%A4%2Fb%2F%C3%A4t%C3%BCr%C3%A4"
Мое первое решение :
class EncodingFixer {
private static final String SLASH_HASH = UUID.randomUUID().toString();
private static final String QUESTION_HASH = UUID.randomUUID().toString();
private static final String EQUALS_HASH = UUID.randomUUID().toString();
private static final String AND_HASH = UUID.randomUUID().toString();
private static final String COLON_HASH = UUID.randomUUID().toString();
EncodingFixer() {
}
String fix(String value) {
if (isBlank(value)) {
return value;
}
return tryFix(value);
}
private String tryFix(String str) {
try {
String replaced = replaceWithHashes(str);
String fixed = java.net.URLEncoder.encode(java.net.URLDecoder.decode(replaced, ISO_8859_1), UTF_8);
return replaceBack(fixed);
} catch (Exception e) {
return str;
}
}
private String replaceWithHashes(String str) {
return str
.replaceAll("/", SLASH_HASH)
.replaceAll("\\?", QUESTION_HASH)
.replaceAll("=", EQUALS_HASH)
.replaceAll("&", AND_HASH)
.replaceAll(":", COLON_HASH);
}
private String replaceBack(String fixed) {
return fixed
.replaceAll(SLASH_HASH, "/")
.replaceAll(QUESTION_HASH, "?")
.replaceAll(EQUALS_HASH, "=")
.replaceAll(AND_HASH, "&")
.replaceAll(COLON_HASH, ":");
}
}
Или это должно быть больше похоже на: ???
Проверьте, является ли ввод URL
Создать URL
Получить путь
Разделить на /
- Исправить каждую часть
- Сложите это вместе
- То же самое для запроса, но немного сложнее
??
Я тоже об этом, но это кажется еще более грязным, чем те, что replaceAll выше: /