Best Practices - Newsletter Nr. 4 - URL-Encoding, Decoding

Ein immer wiederkehrendes Thema ist Encoding und Decoding von URL’s. Oft wird geglaubt, dass Decoding und Encoding ein Thema ist, welches zentral gelöst ist. Aber immer wieder gibt es damit Probleme bzw. tauchen Fragen auf.

 

Im CQ/AEM kümmert sich das Sling-Framework bzw. darunter liegende Frameworks um das Decoding der URL‘s von eingehenden Requests. Wird jedoch ein serverseitiger Redirect ausgelöst, müssen alle Zeichen, die nicht in der US-ASCII-Zeichentabelle enthalten sind, maskiert werden. Wofür ist dies notwendig? Alle Pfade im CQ werden doch immer korrekt abgelegt und somit sollte ein Encoding nicht notwendig sein. Wenn jedoch mit suchmaschinenoptimierten Namen gearbeitet wird, können diese auch Umlaute oder z.B. auch kyrillische Zeichen enthalten. Diese müssen zwingend kodiert werden.

Dies kann am effektivsten mit der Klasse java.net.URI gelöst werden.

 

/**

 * encodes an URL to ASCII. An URL only can contain allowed characters. Every other character

 * has to be percent-encodes.

 *

 * @seeen.wikipedia.org/wiki/Percent-encoding

 * @param url

 * the URL to encode.

 * @return the encoded URL.

 */

 privatestatic String encodeUrl(final String url){

 

    try{

        returnnew URI(url.replace(' ','+')).toASCIIString();

    }catch(URISyntaxException ex){

        LOG.error("the given URL '%s' can't be encoded", ex);

        return url;

    }

 }

 

Folgende Zeichen sind beim Aufruf von new URI nicht erlaubt und führen zu einer URISyntaxException.

", %, :, <, >, [, \, ], ^, `, {, |, }

Bereits mit Prozent encodierte Werte wie z.B. %2D für "" sind erlaubt.

 

Wird nur ein Encoding für z.B. ein Pfadsegment benötigt, kann dies mit folgender Funktion erledigt werden.

 

 /**

 * Encode and normalize a URL segment to UTF-8

 *

 * @param segment

 * a segment from a URL

 * @return the encoded segment

 */

 publicstatic String encodeSegment(final String segment){

 

    String encodeSegment = segment;

    try{

    encodeSegment = Normalizer.normalize(encodeSegment, Normalizer.Form.NFC);

    encodeSegment = URLEncoder.encode(encodeSegment, CharEncoding.UTF_8);

    }catch(UnsupportedEncodingException e){

        LOG.error("the given segment '"+ segment +"' can't be encoded", e);

    }

    return encodeSegment;

 }

 

Hier wird eine Normalisierung der Zeichenkette und danach ein URL-Encoding durchgeführt. Dies funktioniert nur für einzelne Zeichenketten. Hat man schon eine komplette URL, muss man auf die Variante mit java.net.URI zurückgreifen.

Ihr Ansprechpartner