Problem: marketing napsuł i czasem w jedno miejsce apki przychodzą linki i frazy ze zwalonym kodowaniem.
Musimy poprawiać błędne kodowanie w jednym miejscu, czasem jest to fraza, czasem url. Chciałbym poprawiać jedynie znaki enkodowane w ISO-8858-1 na odpowiedniki UTFowe. Jeśli do poprawki przyjdzie url, to decode/encode całości nie wchodzi w gre, bo zmienia mi wszystko, a nie tylko błęde znaki (/ : ? =). Niby mam rozwiązanie, które w pełni wystarcza na nasze potrzeby ale jakoś nie do końca jestem do niego przekonany i rozglądam się za alternatywą...
Miał ktoś podobny problem albo zna może jakąś libke, która zrobi encode/decode z wyłączeniem niektórych znaków? :D
Coś typu decode(String value, char[] ignored)
Edit: jeszcze chciałem rozbić urla na części i babrać się z pathem i query osobno ale jak sobie przeanalizowałem co trzeba zrobić to wyjdzie bajzel
Przykłady:
// zły input
"http://jakis.host/dupa/a/%e4t%fcr%E4/b/%e4t%fcr%E4"
"t%E9l%E9phone"
// dobry output
"http://jakis.host/dupa/a/%C3%A4t%C3%BCr%C3%A4/b/%C3%A4t%C3%BCr%C3%A4"
"t%C3%A9l%C3%A9phone"
// very niedobry output
"http%3A%2F%2Fjakis.host%2Fdupa%2Fa%2F%C3%A4t%C3%BCr%C3%A4%2Fb%2F%C3%A4t%C3%BCr%C3%A4"
Podejście nr 1:
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, ":");
}
}