ISO-8858-1 na UTF-8 w url path

ISO-8858-1 na UTF-8 w url path
baant
  • Rejestracja:ponad 11 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
  • Postów:524
0

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:

Kopiuj
// 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:

Kopiuj
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, ":");
    }
}
edytowany 3x, ostatnio: baant
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 dni
  • Postów:2370
1
  1. Dlaczego problemu nie można naprawić u źródła, tylko mieć jakieś obejście w aplikacji?
  2. Dlaczego marketing miałby wiedzieć coś n/t kodowania znaków? ;) Ale skoro napsuł, to co stoi na przeszkodzie, żeby naprawił?
edytowany 1x, ostatnio: yarel
baant
  • Rejestracja:ponad 11 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
  • Postów:524
0
yarel napisał(a):
  1. Dlaczego problemu nie można naprawić u źródła, tylko mieć jakieś obejście w aplikacji?
  2. Dlaczego marketing miałby wiedzieć coś n/t kodowania znaków? ;) Ale skoro napsuł, to co stoi na przeszkodzie, żeby naprawił?

Coś w reklamach namieszali i poszło w świat. Wg niemieckiej "góry" nie można już naprawić u źródła

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 dni
  • Postów:2370
2

A ile masz tych złych danych? Może statyczna mapa da radę? "ZŁE" -> "DOBRE" ?

baant
a jak napsują znowu? :/ była już taka sytuacja kiedyś z trzema znakami i poprawialiśmy te 3 znaki, po czym popsuli jeszcze bardziej :D wolałbym się zabezpieczyć na przyszłość.
baant
  • Rejestracja:ponad 11 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
  • Postów:524
0
yarel napisał(a):

A ile masz tych złych danych? Może statyczna mapa da radę? "ZŁE" -> "DOBRE" ?

To już może łatwiej by było wziąć co trzeba z tabelki ISO-xxx, dać odpowiedniki UTFowe i podmieniać :) hmm

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 dni
  • Postów:2370
2

Implementować można różne obejścia, ale jak nie naprawią procesu, to problem będzie powracał.

Jak dla mnie:

  • Marketing powinien mieć porządny niemiecki szablon excelowy z makrem, które to makro sprawdzi poprawność przed publikacją ;-)
  • Drugi szablon, gdzie będą wypełniać: ZŁE -> DOBRE i karmić takim konfigiem Twoje obejście problemu.

W ten sposób rozwiązanie robisz raz i jak napsują to wystarczy, że dostarczą odpowiednie dane.

baant
  • Rejestracja:ponad 11 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
  • Postów:524
0

Nawet jeśli naprawimy proces u źródła to złe już poszło w swiat i trzeba się zabezpieczyć :)

MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:8 minut
1
baant napisał(a):
Kopiuj
// zły input
"http://jakis.host/dupa/a/%e4t%fcr%E4/b/%e4t%fcr%E4"
"t%E9l%E9phone"

Z tego co pamiętam (kiedyś przekopywałem się przez odpowiedni RFC) to jest jak najbardziej poprawny url.
Jeśli ten url przychodzi jako część request-a lub response, to trzeba po prostu wsiąść z HTTP header jaki jest encoding i po zdekodowaniu procentów wykonać poprawną konwersję z tego kodowania do String.
Nie znam się na Java, ale z tego co kiedyś liznąłem problemy z URI/URL w Java, to najlepiej używać rozwiązań od Apache.
Dlatego może lepiej zajrzyj tutaj


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.