You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Joel Halbert <jo...@su3analytics.com> on 2010/06/18 17:08:09 UTC

Customising T5 URL Encoding

Tapestry appears to URL encode spaces as "$0020"

e.g.
http://localhost:8080/web/buy/sports$0020shoes


I would much prefer to use standard encoding such as:

http://localhost:8080/web/buy/sports+shoes
or
http://localhost:8080/web/buy/sports%20shoes


Is it possible to configure or override this behaviour?

Re: Customising T5 URL Encoding

Posted by Christophe Cordenier <ch...@gmail.com>.
You can override every service of Tapestry, you have three ways to achieve
this :

1. Decoration

http://tapestry.apache.org/tapestry5.1/tapestry-ioc/decorator.html

2. Advice

http://tapestry.apache.org/tapestry5.1/tapestry-ioc/advice.html

3. Complete override

http://tapestry.apache.org/tapestry5.1/guide/alias.html

2010/6/18 Joel Halbert <jo...@su3analytics.com>

> Tapestry appears to URL encode spaces as "$0020"
>
> e.g.
> http://localhost:8080/web/buy/sports$0020shoes
>
>
> I would much prefer to use standard encoding such as:
>
> http://localhost:8080/web/buy/sports+shoes
> or
> http://localhost:8080/web/buy/sports%20shoes
>
>
> Is it possible to configure or override this behaviour?
>



-- 
Regards,
Christophe Cordenier.

Developer of wooki @wookicentral.com

Re: Customising T5 URL Encoding

Posted by Jochen Frey <jo...@jochenfrey.com>.
+1
On Mar 12, 2012, at 8:57 AM, David Canteros wrote:

> +1
> I have several problems with the integration of my Tapestry tools and other
> non-tapestry tools, all of this caused by tapestry URLEncoder. I solved
> this by overriding URLEncoder, but your proposal would be a more elegant
> solution
> 
> 
> ------------------------------------------------------------------
> David Germán Canteros
> 
> 
> 2012/3/11 Paul Stanton <pa...@mapshed.com.au>
> 
>> +1
>> 
>> possibly with 3 options? :
>> 
>> a) tomcat compatible default encoding
>> b) jetty compatible default encoding
>> c) tapestry encoding
>> 
>> On 21/06/2010 6:34 AM, Joel Halbert wrote:
>> 
>>> Agreed, it would be good to have this as a configuration option.
>>> 
>>> On 20/06/10 19:20, Kai Weber wrote:
>>> 
>>>> * Nicolas Bouillon<ni...@bouil.org>:
>>>> 
>>>> The Tapestry URL encoding is not a problem for me in general, just for
>>>>> one
>>>>> use case when i wanted to migrate a site to tapestry and keeping the
>>>>> same
>>>>> URL (with accents, spaces, dashes, underscores and so on).
>>>>> 
>>>> It is a problem if you get called by other webapps. If they call your
>>>> page with the standard URL encoding scheme you have a problem.  Say you
>>>> have
>>>> 
>>>> onActivate(String emailadress)
>>>> 
>>>> no one can call your page because the expected encoding for @ in T5 is
>>>> $0040 where the rest of the world would send you an @.
>>>> 
>>>> We use only query strings or numerical IDs as parameters for pages which
>>>> can get called from external sites.
>>>> 
>>>> I would like to see configuration option to switch or disable the
>>>> URLEncoder completly.
>>>> 
>>>> Kai
>>>> 
>>>> ------------------------------**------------------------------**
>>>> ---------
>>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>> 
>>>> 
>>>> 
>>> 
>>> ------------------------------**------------------------------**---------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>> 
>>> 
>>> 
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
>> For additional commands, e-mail: users-help@tapestry.apache.org
>> 
>> 

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


Re: Customising T5 URL Encoding

Posted by David Canteros <da...@gmail.com>.
+1
I have several problems with the integration of my Tapestry tools and other
non-tapestry tools, all of this caused by tapestry URLEncoder. I solved
this by overriding URLEncoder, but your proposal would be a more elegant
solution


------------------------------------------------------------------
David Germán Canteros


2012/3/11 Paul Stanton <pa...@mapshed.com.au>

> +1
>
> possibly with 3 options? :
>
> a) tomcat compatible default encoding
> b) jetty compatible default encoding
> c) tapestry encoding
>
> On 21/06/2010 6:34 AM, Joel Halbert wrote:
>
>> Agreed, it would be good to have this as a configuration option.
>>
>> On 20/06/10 19:20, Kai Weber wrote:
>>
>>> * Nicolas Bouillon<ni...@bouil.org>:
>>>
>>>  The Tapestry URL encoding is not a problem for me in general, just for
>>>> one
>>>> use case when i wanted to migrate a site to tapestry and keeping the
>>>> same
>>>> URL (with accents, spaces, dashes, underscores and so on).
>>>>
>>> It is a problem if you get called by other webapps. If they call your
>>> page with the standard URL encoding scheme you have a problem.  Say you
>>> have
>>>
>>> onActivate(String emailadress)
>>>
>>> no one can call your page because the expected encoding for @ in T5 is
>>> $0040 where the rest of the world would send you an @.
>>>
>>> We use only query strings or numerical IDs as parameters for pages which
>>> can get called from external sites.
>>>
>>> I would like to see configuration option to switch or disable the
>>> URLEncoder completly.
>>>
>>> Kai
>>>
>>> ------------------------------**------------------------------**
>>> ---------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>>
>>
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.**apache.org<us...@tapestry.apache.org>
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Customising T5 URL Encoding

Posted by Paul Stanton <pa...@mapshed.com.au>.
+1

possibly with 3 options? :

a) tomcat compatible default encoding
b) jetty compatible default encoding
c) tapestry encoding

On 21/06/2010 6:34 AM, Joel Halbert wrote:
> Agreed, it would be good to have this as a configuration option.
>
> On 20/06/10 19:20, Kai Weber wrote:
>> * Nicolas Bouillon<ni...@bouil.org>:
>>
>>> The Tapestry URL encoding is not a problem for me in general, just 
>>> for one
>>> use case when i wanted to migrate a site to tapestry and keeping the 
>>> same
>>> URL (with accents, spaces, dashes, underscores and so on).
>> It is a problem if you get called by other webapps. If they call your
>> page with the standard URL encoding scheme you have a problem.  Say you
>> have
>>
>> onActivate(String emailadress)
>>
>> no one can call your page because the expected encoding for @ in T5 is
>> $0040 where the rest of the world would send you an @.
>>
>> We use only query strings or numerical IDs as parameters for pages which
>> can get called from external sites.
>>
>> I would like to see configuration option to switch or disable the
>> URLEncoder completly.
>>
>> Kai
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Customising T5 URL Encoding

Posted by Joel Halbert <jo...@su3analytics.com>.
Agreed, it would be good to have this as a configuration option.

On 20/06/10 19:20, Kai Weber wrote:
> * Nicolas Bouillon<ni...@bouil.org>:
>
>    
>> The Tapestry URL encoding is not a problem for me in general, just for one
>> use case when i wanted to migrate a site to tapestry and keeping the same
>> URL (with accents, spaces, dashes, underscores and so on).
>>      
> It is a problem if you get called by other webapps. If they call your
> page with the standard URL encoding scheme you have a problem.  Say you
> have
>
> onActivate(String emailadress)
>
> no one can call your page because the expected encoding for @ in T5 is
> $0040 where the rest of the world would send you an @.
>
> We use only query strings or numerical IDs as parameters for pages which
> can get called from external sites.
>
> I would like to see configuration option to switch or disable the
> URLEncoder completly.
>
> Kai
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
>    


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Customising T5 URL Encoding

Posted by Kai Weber <ka...@glorybox.de>.
* Nicolas Bouillon <ni...@bouil.org>:

> The Tapestry URL encoding is not a problem for me in general, just for one
> use case when i wanted to migrate a site to tapestry and keeping the same
> URL (with accents, spaces, dashes, underscores and so on).

It is a problem if you get called by other webapps. If they call your
page with the standard URL encoding scheme you have a problem.  Say you
have

onActivate(String emailadress)

no one can call your page because the expected encoding for @ in T5 is
$0040 where the rest of the world would send you an @.

We use only query strings or numerical IDs as parameters for pages which
can get called from external sites.

I would like to see configuration option to switch or disable the
URLEncoder completly.

Kai

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Customising T5 URL Encoding

Posted by Nicolas Bouillon <ni...@bouil.org>.
The Tapestry URL encoding is not a problem for me in general, just for one
use case when i wanted to migrate a site to tapestry and keeping the same
URL (with accents, spaces, dashes, underscores and so on).

On Fri, 18 Jun 2010 17:20:36 -0700, Howard Lewis Ship <hl...@gmail.com>
wrote:
> Tapestry does its own encoding because Jetty and Tomcat differ on
> whether you get the decoded or raw strings.  Creating another option,
> that would work the same across servlet containers, seemed to make
> sense at the time.
> 
> On Fri, Jun 18, 2010 at 8:50 AM, Nicolas Bouillon <ni...@bouil.org>
> wrote:
>> Hi,
>>
>> Here is how i've overrided this behavior, to allow URL with "%20" or
>> other
>> chars as incomming request. It quite a copy/paste tweaking of the
>> original
>> UrlEncoderImpl from Tapestry 5.1.0.5.
>>
>> public class AppModule {
>>    .....
>>    public static void contributeServiceOverride(
>>            MappedConfiguration<Class, Object> configuration) {
>>        configuration.add(URLEncoder.class, new MyURLEncoderImpl());
>>    }
>>    .....
>> }
>>
>>
>> package org.bouil.tapestry.services;
>>
>> import java.io.UnsupportedEncodingException;
>> import java.util.BitSet;
>>
>> import org.apache.tapestry5.ioc.internal.util.Defense;
>> import org.apache.tapestry5.services.URLEncoder;
>>
>> public class MyURLEncoderImpl implements URLEncoder {
>>    static final String ENCODED_NULL = "$N";
>>    static final String ENCODED_BLANK = "$B";
>>
>>    /**
>>     * Bit set indicating which character are safe to pass through (when
>>     * encoding or decoding) as-is. All other characters are encoded as
a
>> kind
>>     * of unicode escape.
>>     */
>>    private final BitSet safeForInput = new BitSet(128);
>>    private final BitSet safeForOutput = new BitSet(128);
>>
>>    {
>>
>> markSafeForInput("aàâäbcçĉdeéèêëfgĝhĥiïîjĵklmnoôöpqrsŝtuùûüvwxyzæœ");
>>
>> markSafeForInput("AÀÂÄBCÇĈDEÉÈÊËFGĜHĤIÏÎĤJĴKLMNOÔÖPQRSŜTUÙÛÜVWXYZÆŒ");
>>        markSafeForInput("01234567890-_.:,'");
>>
>>        markSafeForOuput("abcdefghijklmnopqrstuvwxyz");
>>        markSafeForOuput("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
>>        markSafeForOuput("01234567890-_.:,'");
>>    }
>>
>>    private void markSafeForInput(String s) {
>>        for (char ch : s.toCharArray()) {
>>            safeForInput.set(ch);
>>        }
>>    }
>>
>>    private void markSafeForOuput(String s) {
>>        for (char ch : s.toCharArray()) {
>>            safeForOutput.set(ch);
>>        }
>>    }
>>
>>    public String encode(String input) {
>>        if (input == null)
>>            return ENCODED_NULL;
>>
>>        if (input.equals(""))
>>            return ENCODED_BLANK;
>>
>>        boolean dirty = false;
>>
>>        int length = input.length();
>>
>>        StringBuilder output = new StringBuilder(length * 2);
>>
>>        for (int i = 0; i < length; i++) {
>>            char ch = input.charAt(i);
>>
>>            if (ch == '$') {
>>                output.append("$$");
>>                dirty = true;
>>                continue;
>>            }
>>
>>            int chAsInt = ch;
>>
>>            if (safeForOutput.get(chAsInt)) {
>>                output.append(ch);
>>                continue;
>>            }
>>
>>            try {
>>                return  java.net.URLEncoder.encode(new String(input),
>> "UTF-8");
>>            } catch (UnsupportedEncodingException e) {
>>                throw new IllegalArgumentException(e);
>>            }
>>            // output.append(String.format("$%04x", chAsInt));
>>            // dirty = true;
>>        }
>>
>>        return dirty ? output.toString() : input;
>>    }
>>
>>    public String decode(String input) {
>>        Defense.notNull(input, "input");
>>
>>        if (input.equals(ENCODED_NULL))
>>            return null;
>>
>>        if (input.equals(ENCODED_BLANK))
>>            return "";
>>
>>        boolean dirty = false;
>>
>>        int length = input.length();
>>
>>        StringBuilder output = new StringBuilder(length * 2);
>>
>>        for (int i = 0; i < length; i++) {
>>            char ch = input.charAt(i);
>>
>>            if (ch == '$') {
>>                dirty = true;
>>
>>                if (i + 1 < length && input.charAt(i + 1) == '$') {
>>                    output.append('$');
>>                    i++;
>>
>>                    dirty = true;
>>                    continue;
>>                }
>>
>>                if (i + 4 < length) {
>>                    String hex = input.substring(i + 1, i + 5);
>>
>>                    try {
>>                        int unicode = Integer.parseInt(hex, 16);
>>
>>                        output.append((char) unicode);
>>                        i += 4;
>>                        dirty = true;
>>                        continue;
>>                    } catch (NumberFormatException ex) {
>>                        // Ignore.
>>                    }
>>                }
>>
>>                throw new IllegalArgumentException(
>>                        String
>>                                .format(
>>                                        "Input string '%s' is not valid;
>> the '$' character at position %d should be followed by another '$' or a
>> four digit hex number (a unicode value).",
>>                                        input, i + 1));
>>            }
>>
>>            if (!safeForInput.get(ch)) {
>>                throw new IllegalArgumentException(
>>                        String
>>                                .format(
>>                                        "Input string '%s' is not valid;
>> the character '%s' at position %d is not valid.",
>>                                        input, ch, i + 1));
>>            }
>>
>>            output.append(ch);
>>        }
>>
>>        return dirty ? output.toString() : input;
>>    }
>> }
>>
>>
>>
>> On Fri, 18 Jun 2010 16:08:09 +0100, Joel Halbert
<jo...@su3analytics.com>
>> wrote:
>>> Tapestry appears to URL encode spaces as "$0020"
>>>
>>> e.g.
>>> http://localhost:8080/web/buy/sports$0020shoes
>>>
>>>
>>> I would much prefer to use standard encoding such as:
>>>
>>> http://localhost:8080/web/buy/sports+shoes
>>> or
>>> http://localhost:8080/web/buy/sports%20shoes
>>>
>>>
>>> Is it possible to configure or override this behaviour?
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Customising T5 URL Encoding

Posted by Joel Halbert <jo...@su3analytics.com>.
Makes sense. I must admit I was curious as to why T5 uses custom 
encoding, so thanks for the explanation.

I'll use Nicolas's solution to override this behaviour.

On 19/06/10 01:20, Howard Lewis Ship wrote:
> Tapestry does its own encoding because Jetty and Tomcat differ on
> whether you get the decoded or raw strings.  Creating another option,
> that would work the same across servlet containers, seemed to make
> sense at the time.
>
> On Fri, Jun 18, 2010 at 8:50 AM, Nicolas Bouillon<ni...@bouil.org>  wrote:
>    
>> Hi,
>>
>> Here is how i've overrided this behavior, to allow URL with "%20" or other
>> chars as incomming request. It quite a copy/paste tweaking of the original
>> UrlEncoderImpl from Tapestry 5.1.0.5.
>>
>> public class AppModule {
>>     .....
>>     public static void contributeServiceOverride(
>>             MappedConfiguration<Class, Object>  configuration) {
>>         configuration.add(URLEncoder.class, new MyURLEncoderImpl());
>>     }
>>     .....
>> }
>>
>>
>> package org.bouil.tapestry.services;
>>
>> import java.io.UnsupportedEncodingException;
>> import java.util.BitSet;
>>
>> import org.apache.tapestry5.ioc.internal.util.Defense;
>> import org.apache.tapestry5.services.URLEncoder;
>>
>> public class MyURLEncoderImpl implements URLEncoder {
>>     static final String ENCODED_NULL = "$N";
>>     static final String ENCODED_BLANK = "$B";
>>
>>     /**
>>      * Bit set indicating which character are safe to pass through (when
>>      * encoding or decoding) as-is. All other characters are encoded as a
>> kind
>>      * of unicode escape.
>>      */
>>     private final BitSet safeForInput = new BitSet(128);
>>     private final BitSet safeForOutput = new BitSet(128);
>>
>>     {
>>
>> markSafeForInput("aàâäbcçĉdeéèêëfgĝhĥiïîjĵklmnoôöpqrsŝtuùûüvwxyzæœ");
>>
>> markSafeForInput("AÀÂÄBCÇĈDEÉÈÊËFGĜHĤIÏÎĤJĴKLMNOÔÖPQRSŜTUÙÛÜVWXYZÆŒ");
>>         markSafeForInput("01234567890-_.:,'");
>>
>>         markSafeForOuput("abcdefghijklmnopqrstuvwxyz");
>>         markSafeForOuput("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
>>         markSafeForOuput("01234567890-_.:,'");
>>     }
>>
>>     private void markSafeForInput(String s) {
>>         for (char ch : s.toCharArray()) {
>>             safeForInput.set(ch);
>>         }
>>     }
>>
>>     private void markSafeForOuput(String s) {
>>         for (char ch : s.toCharArray()) {
>>             safeForOutput.set(ch);
>>         }
>>     }
>>
>>     public String encode(String input) {
>>         if (input == null)
>>             return ENCODED_NULL;
>>
>>         if (input.equals(""))
>>             return ENCODED_BLANK;
>>
>>         boolean dirty = false;
>>
>>         int length = input.length();
>>
>>         StringBuilder output = new StringBuilder(length * 2);
>>
>>         for (int i = 0; i<  length; i++) {
>>             char ch = input.charAt(i);
>>
>>             if (ch == '$') {
>>                 output.append("$$");
>>                 dirty = true;
>>                 continue;
>>             }
>>
>>             int chAsInt = ch;
>>
>>             if (safeForOutput.get(chAsInt)) {
>>                 output.append(ch);
>>                 continue;
>>             }
>>
>>             try {
>>                 return  java.net.URLEncoder.encode(new String(input),
>> "UTF-8");
>>             } catch (UnsupportedEncodingException e) {
>>                 throw new IllegalArgumentException(e);
>>             }
>>             // output.append(String.format("$%04x", chAsInt));
>>             // dirty = true;
>>         }
>>
>>         return dirty ? output.toString() : input;
>>     }
>>
>>     public String decode(String input) {
>>         Defense.notNull(input, "input");
>>
>>         if (input.equals(ENCODED_NULL))
>>             return null;
>>
>>         if (input.equals(ENCODED_BLANK))
>>             return "";
>>
>>         boolean dirty = false;
>>
>>         int length = input.length();
>>
>>         StringBuilder output = new StringBuilder(length * 2);
>>
>>         for (int i = 0; i<  length; i++) {
>>             char ch = input.charAt(i);
>>
>>             if (ch == '$') {
>>                 dirty = true;
>>
>>                 if (i + 1<  length&&  input.charAt(i + 1) == '$') {
>>                     output.append('$');
>>                     i++;
>>
>>                     dirty = true;
>>                     continue;
>>                 }
>>
>>                 if (i + 4<  length) {
>>                     String hex = input.substring(i + 1, i + 5);
>>
>>                     try {
>>                         int unicode = Integer.parseInt(hex, 16);
>>
>>                         output.append((char) unicode);
>>                         i += 4;
>>                         dirty = true;
>>                         continue;
>>                     } catch (NumberFormatException ex) {
>>                         // Ignore.
>>                     }
>>                 }
>>
>>                 throw new IllegalArgumentException(
>>                         String
>>                                 .format(
>>                                         "Input string '%s' is not valid;
>> the '$' character at position %d should be followed by another '$' or a
>> four digit hex number (a unicode value).",
>>                                         input, i + 1));
>>             }
>>
>>             if (!safeForInput.get(ch)) {
>>                 throw new IllegalArgumentException(
>>                         String
>>                                 .format(
>>                                         "Input string '%s' is not valid;
>> the character '%s' at position %d is not valid.",
>>                                         input, ch, i + 1));
>>             }
>>
>>             output.append(ch);
>>         }
>>
>>         return dirty ? output.toString() : input;
>>     }
>> }
>>
>>
>>
>> On Fri, 18 Jun 2010 16:08:09 +0100, Joel Halbert<jo...@su3analytics.com>
>> wrote:
>>      
>>> Tapestry appears to URL encode spaces as "$0020"
>>>
>>> e.g.
>>> http://localhost:8080/web/buy/sports$0020shoes
>>>
>>>
>>> I would much prefer to use standard encoding such as:
>>>
>>> http://localhost:8080/web/buy/sports+shoes
>>> or
>>> http://localhost:8080/web/buy/sports%20shoes
>>>
>>>
>>> Is it possible to configure or override this behaviour?
>>>        
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>>      
>
>
>    


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Customising T5 URL Encoding

Posted by Howard Lewis Ship <hl...@gmail.com>.
Tapestry does its own encoding because Jetty and Tomcat differ on
whether you get the decoded or raw strings.  Creating another option,
that would work the same across servlet containers, seemed to make
sense at the time.

On Fri, Jun 18, 2010 at 8:50 AM, Nicolas Bouillon <ni...@bouil.org> wrote:
> Hi,
>
> Here is how i've overrided this behavior, to allow URL with "%20" or other
> chars as incomming request. It quite a copy/paste tweaking of the original
> UrlEncoderImpl from Tapestry 5.1.0.5.
>
> public class AppModule {
>    .....
>    public static void contributeServiceOverride(
>            MappedConfiguration<Class, Object> configuration) {
>        configuration.add(URLEncoder.class, new MyURLEncoderImpl());
>    }
>    .....
> }
>
>
> package org.bouil.tapestry.services;
>
> import java.io.UnsupportedEncodingException;
> import java.util.BitSet;
>
> import org.apache.tapestry5.ioc.internal.util.Defense;
> import org.apache.tapestry5.services.URLEncoder;
>
> public class MyURLEncoderImpl implements URLEncoder {
>    static final String ENCODED_NULL = "$N";
>    static final String ENCODED_BLANK = "$B";
>
>    /**
>     * Bit set indicating which character are safe to pass through (when
>     * encoding or decoding) as-is. All other characters are encoded as a
> kind
>     * of unicode escape.
>     */
>    private final BitSet safeForInput = new BitSet(128);
>    private final BitSet safeForOutput = new BitSet(128);
>
>    {
>
> markSafeForInput("aàâäbcçĉdeéèêëfgĝhĥiïîjĵklmnoôöpqrsŝtuùûüvwxyzæœ");
>
> markSafeForInput("AÀÂÄBCÇĈDEÉÈÊËFGĜHĤIÏÎĤJĴKLMNOÔÖPQRSŜTUÙÛÜVWXYZÆŒ");
>        markSafeForInput("01234567890-_.:,'");
>
>        markSafeForOuput("abcdefghijklmnopqrstuvwxyz");
>        markSafeForOuput("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
>        markSafeForOuput("01234567890-_.:,'");
>    }
>
>    private void markSafeForInput(String s) {
>        for (char ch : s.toCharArray()) {
>            safeForInput.set(ch);
>        }
>    }
>
>    private void markSafeForOuput(String s) {
>        for (char ch : s.toCharArray()) {
>            safeForOutput.set(ch);
>        }
>    }
>
>    public String encode(String input) {
>        if (input == null)
>            return ENCODED_NULL;
>
>        if (input.equals(""))
>            return ENCODED_BLANK;
>
>        boolean dirty = false;
>
>        int length = input.length();
>
>        StringBuilder output = new StringBuilder(length * 2);
>
>        for (int i = 0; i < length; i++) {
>            char ch = input.charAt(i);
>
>            if (ch == '$') {
>                output.append("$$");
>                dirty = true;
>                continue;
>            }
>
>            int chAsInt = ch;
>
>            if (safeForOutput.get(chAsInt)) {
>                output.append(ch);
>                continue;
>            }
>
>            try {
>                return  java.net.URLEncoder.encode(new String(input),
> "UTF-8");
>            } catch (UnsupportedEncodingException e) {
>                throw new IllegalArgumentException(e);
>            }
>            // output.append(String.format("$%04x", chAsInt));
>            // dirty = true;
>        }
>
>        return dirty ? output.toString() : input;
>    }
>
>    public String decode(String input) {
>        Defense.notNull(input, "input");
>
>        if (input.equals(ENCODED_NULL))
>            return null;
>
>        if (input.equals(ENCODED_BLANK))
>            return "";
>
>        boolean dirty = false;
>
>        int length = input.length();
>
>        StringBuilder output = new StringBuilder(length * 2);
>
>        for (int i = 0; i < length; i++) {
>            char ch = input.charAt(i);
>
>            if (ch == '$') {
>                dirty = true;
>
>                if (i + 1 < length && input.charAt(i + 1) == '$') {
>                    output.append('$');
>                    i++;
>
>                    dirty = true;
>                    continue;
>                }
>
>                if (i + 4 < length) {
>                    String hex = input.substring(i + 1, i + 5);
>
>                    try {
>                        int unicode = Integer.parseInt(hex, 16);
>
>                        output.append((char) unicode);
>                        i += 4;
>                        dirty = true;
>                        continue;
>                    } catch (NumberFormatException ex) {
>                        // Ignore.
>                    }
>                }
>
>                throw new IllegalArgumentException(
>                        String
>                                .format(
>                                        "Input string '%s' is not valid;
> the '$' character at position %d should be followed by another '$' or a
> four digit hex number (a unicode value).",
>                                        input, i + 1));
>            }
>
>            if (!safeForInput.get(ch)) {
>                throw new IllegalArgumentException(
>                        String
>                                .format(
>                                        "Input string '%s' is not valid;
> the character '%s' at position %d is not valid.",
>                                        input, ch, i + 1));
>            }
>
>            output.append(ch);
>        }
>
>        return dirty ? output.toString() : input;
>    }
> }
>
>
>
> On Fri, 18 Jun 2010 16:08:09 +0100, Joel Halbert <jo...@su3analytics.com>
> wrote:
>> Tapestry appears to URL encode spaces as "$0020"
>>
>> e.g.
>> http://localhost:8080/web/buy/sports$0020shoes
>>
>>
>> I would much prefer to use standard encoding such as:
>>
>> http://localhost:8080/web/buy/sports+shoes
>> or
>> http://localhost:8080/web/buy/sports%20shoes
>>
>>
>> Is it possible to configure or override this behaviour?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

Re: Customising T5 URL Encoding

Posted by Nicolas Bouillon <ni...@bouil.org>.
Hi,

Here is how i've overrided this behavior, to allow URL with "%20" or other
chars as incomming request. It quite a copy/paste tweaking of the original
UrlEncoderImpl from Tapestry 5.1.0.5.

public class AppModule {
    .....
    public static void contributeServiceOverride(
            MappedConfiguration<Class, Object> configuration) {
        configuration.add(URLEncoder.class, new MyURLEncoderImpl());
    }
    .....
}


package org.bouil.tapestry.services;

import java.io.UnsupportedEncodingException;
import java.util.BitSet;

import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.services.URLEncoder;

public class MyURLEncoderImpl implements URLEncoder {
    static final String ENCODED_NULL = "$N";
    static final String ENCODED_BLANK = "$B";

    /**
     * Bit set indicating which character are safe to pass through (when
     * encoding or decoding) as-is. All other characters are encoded as a
kind
     * of unicode escape.
     */
    private final BitSet safeForInput = new BitSet(128);
    private final BitSet safeForOutput = new BitSet(128);

    {
       
markSafeForInput("aàâäbcçĉdeéèêëfgĝhĥiïîjĵklmnoôöpqrsŝtuùûüvwxyzæœ");
       
markSafeForInput("AÀÂÄBCÇĈDEÉÈÊËFGĜHĤIÏÎĤJĴKLMNOÔÖPQRSŜTUÙÛÜVWXYZÆŒ");
        markSafeForInput("01234567890-_.:,'");

        markSafeForOuput("abcdefghijklmnopqrstuvwxyz");
        markSafeForOuput("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        markSafeForOuput("01234567890-_.:,'");
    }

    private void markSafeForInput(String s) {
        for (char ch : s.toCharArray()) {
            safeForInput.set(ch);
        }
    }

    private void markSafeForOuput(String s) {
        for (char ch : s.toCharArray()) {
            safeForOutput.set(ch);
        }
    }

    public String encode(String input) {
        if (input == null)
            return ENCODED_NULL;

        if (input.equals(""))
            return ENCODED_BLANK;

        boolean dirty = false;

        int length = input.length();

        StringBuilder output = new StringBuilder(length * 2);

        for (int i = 0; i < length; i++) {
            char ch = input.charAt(i);

            if (ch == '$') {
                output.append("$$");
                dirty = true;
                continue;
            }

            int chAsInt = ch;

            if (safeForOutput.get(chAsInt)) {
                output.append(ch);
                continue;
            }
            
            try {
                return  java.net.URLEncoder.encode(new String(input),
"UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new IllegalArgumentException(e);
            }
            // output.append(String.format("$%04x", chAsInt));
            // dirty = true;
        }

        return dirty ? output.toString() : input;
    }

    public String decode(String input) {
        Defense.notNull(input, "input");

        if (input.equals(ENCODED_NULL))
            return null;

        if (input.equals(ENCODED_BLANK))
            return "";

        boolean dirty = false;

        int length = input.length();

        StringBuilder output = new StringBuilder(length * 2);

        for (int i = 0; i < length; i++) {
            char ch = input.charAt(i);

            if (ch == '$') {
                dirty = true;

                if (i + 1 < length && input.charAt(i + 1) == '$') {
                    output.append('$');
                    i++;

                    dirty = true;
                    continue;
                }

                if (i + 4 < length) {
                    String hex = input.substring(i + 1, i + 5);

                    try {
                        int unicode = Integer.parseInt(hex, 16);

                        output.append((char) unicode);
                        i += 4;
                        dirty = true;
                        continue;
                    } catch (NumberFormatException ex) {
                        // Ignore.
                    }
                }

                throw new IllegalArgumentException(
                        String
                                .format(
                                        "Input string '%s' is not valid;
the '$' character at position %d should be followed by another '$' or a
four digit hex number (a unicode value).",
                                        input, i + 1));
            }

            if (!safeForInput.get(ch)) {
                throw new IllegalArgumentException(
                        String
                                .format(
                                        "Input string '%s' is not valid;
the character '%s' at position %d is not valid.",
                                        input, ch, i + 1));
            }

            output.append(ch);
        }

        return dirty ? output.toString() : input;
    }
}



On Fri, 18 Jun 2010 16:08:09 +0100, Joel Halbert <jo...@su3analytics.com>
wrote:
> Tapestry appears to URL encode spaces as "$0020"
> 
> e.g.
> http://localhost:8080/web/buy/sports$0020shoes
> 
> 
> I would much prefer to use standard encoding such as:
> 
> http://localhost:8080/web/buy/sports+shoes
> or
> http://localhost:8080/web/buy/sports%20shoes
> 
> 
> Is it possible to configure or override this behaviour?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org