tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Tapestry > URL rewriting
Date Tue, 12 Oct 2010 08:12:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/12/_/styles/combined.css?spaceKey=TAPESTRY&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/TAPESTRY/URL+rewriting">URL
rewriting</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~ccordenier">Christophe
Cordenier</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        [fix] BOTH Code snippet was not compiling<br />
    </div>
        <br/>
                         <h4>Changes (5)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >public static void contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt;
configuration) <br>{ <br></td></tr>
            <tr><td class="diff-unchanged" >    URLRewriterRule rule = new URLRewriterRule()
 <br>    { <br></td></tr>
            <tr><td class="diff-unchanged" >        public Request process(Request
request, URLRewriteContext context) <br>        { <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >                } <br>     
          String pageName = request.getPath().substring(1,request.getPath().indexOf(&#39;/&#39;,1));
<br></td></tr>
            <tr><td class="diff-changed-lines" >return new <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">SimpleRequest(request,path.replaceAll(pageName,pageName</span>
<span class="diff-added-words"style="background-color: #dfd;">SimpleRequestWrapper(request,
request.getPath().replaceAll(pageName,pageName</span> + &quot;page&quot;));
<br></td></tr>
            <tr><td class="diff-unchanged" >            } <br>         
  else <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >                    String pageName
= context.getPageParameters().getLogicalPageName().toLowerCase(); <br>             
      String newPageName = pageName.replaceAll(&quot;page$&quot;,&quot;&quot;);
<br></td></tr>
            <tr><td class="diff-changed-lines" >return new <span class="diff-changed-words">SimpleRequest<span
class="diff-added-chars"style="background-color: #dfd;">Wrapper</span>(request,path.replaceAll(pageName,newPageName)<span
class="diff-added-chars"style="background-color: #dfd;">)</span>;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >               } <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
              return request; <br></td></tr>
            <tr><td class="diff-unchanged" >            } <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
           return request; <br></td></tr>
            <tr><td class="diff-unchanged" >        } <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >            return RewriteRuleApplicability.BOTH;
<br>        } <br></td></tr>
            <tr><td class="diff-unchanged" >    }; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="URLrewriting-TapestryURLRewritingSupport"></a>Tapestry
URL Rewriting Support</h1>

<p>Since 5.1.0.1, Tapestry has basic support for URL rewriting. Incoming requests and
links generated by Tapestry can be rewritten using exactly the same API. It is based on a
chain of <tt>URLRewriterRule</tt> interfaces. These rules are executed before
all other Tapestry request handling, so it does not even know that the received request is
not the original one.</p>

<p>Each URL rewriter rule, in its <tt>Request process</tt>, can choose between
returning another <tt>Request</tt>, effectively rewriting it, or returning the
received request unchanged, meaning that this rule does not apply to that request.</p>

<p>To create facilitate <tt>Request</tt> creation, Tapestry provides the
<tt>SimpleRequestWrapper</tt> class. It wraps an <tt>Request</tt>,
delegating all methods except <tt>getPath()</tt> and <tt>getServerName()</tt>.
More request wrappers may be added in the future on demand.</p>

<h1><a name="URLrewriting-Configuration"></a>Configuration</h1>

<p>Tapestry's URL rewriting support is configured by Tapestry-Ioc through contribution
of <tt>URLRewriterRule}}s to the {{URLRewriter</tt> service. The following example
is part of the Tapestry's tests.</p>

<h1><a name="URLrewriting-Simpleexampleofrulechaining"></a>Simple example
of rule chaining</h1>

<p>This example just rewrites all incoming requests to <tt>/struts</tt>
to <tt>/tapestry</tt>. In your <tt>AppModule</tt> or any other Tapestry-IoC
module class:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

<span class="code-keyword">public</span> <span class="code-keyword">static</span>
void contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
{
    
    URLRewriterRule rule = <span class="code-keyword">new</span> URLRewriterRule()

    {

        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-keyword">final</span> <span class="code-object">String</span>
path = request.getPath();
            <span class="code-keyword">if</span> (path.equals(<span class="code-quote">"/struts"</span>))
            {
                request = <span class="code-keyword">new</span> SimpleRequestWrapper(request,
<span class="code-quote">"/tapestry"</span>);
            }
            
            <span class="code-keyword">return</span> request;
            
        }

        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.INBOUND;
        }
        
    };
    
    configuration.add(<span class="code-quote">"myrule"</span>, rule);
}

</pre>
</div></div>

<h1><a name="URLrewriting-Exampleofrulechaining"></a>Example of rule chaining</h1>

<p>In your <tt>AppModule</tt> or any other Tapestry-IoC module class.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

<span class="code-keyword">public</span> <span class="code-keyword">static</span>
void contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
{
    
    URLRewriterRule rule1 = <span class="code-keyword">new</span> URLRewriterRule()
    {

        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-keyword">final</span> <span class="code-object">String</span>
path = request.getPath();
            <span class="code-keyword">if</span> (path.equals(<span class="code-quote">"/struts"</span>))

            {
                request = <span class="code-keyword">new</span> SimpleRequestWrapper(request,
<span class="code-quote">"/jsf"</span>);
            }
            
            <span class="code-keyword">return</span> request;
            
        }

        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.INBOUND;
        } 
        
    };
    
    URLRewriterRule rule2 = <span class="code-keyword">new</span> URLRewriterRule()
    {

        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-keyword">final</span> <span class="code-object">String</span>
path = request.getPath();
            <span class="code-keyword">if</span> (path.equals(<span class="code-quote">"/jsf"</span>))

            {
                request = <span class="code-keyword">new</span> SimpleRequestWrapper(request,
<span class="code-quote">"/tapestry"</span>);
            }
            <span class="code-keyword">return</span> request;
            
        }
        
        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.INBOUND;
        }

    };
    
    URLRewriterRule rule3 = <span class="code-keyword">new</span> URLRewriterRule()
    {

        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-object">String</span> path = request.getPath();
            <span class="code-keyword">if</span> (path.equals(<span class="code-quote">"/tapestry"</span>))

            {
                path = <span class="code-quote">"/urlrewritesuccess"</span>;
                request = <span class="code-keyword">new</span> SimpleRequestWrapper(request,
path);
            }
            <span class="code-keyword">return</span> request;
            
        }
        
        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.INBOUND;
        }

    };
    
    URLRewriterRule rule4 = <span class="code-keyword">new</span> URLRewriterRule()
    {

        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-object">String</span> serverName = request.getServerName();
            <span class="code-object">String</span> path = request.getPath();
            <span class="code-keyword">final</span> <span class="code-object">String</span>
pathToRewrite = <span class="code-quote">"/urlrewritesuccess/login"</span>;
            <span class="code-keyword">if</span> (serverName.equals(<span class="code-quote">"localhost"</span>)
&amp;&amp; path.equalsIgnoreCase(pathToRewrite)) 
            {
                request = <span class="code-keyword">new</span> SimpleRequestWrapper(request,
<span class="code-quote">"http:<span class="code-comment">//login.domain.com"</span>,
<span class="code-quote">"/"</span>);
</span>            }
            <span class="code-keyword">return</span> request;
            
        }

        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.OUTBOUND;
        }


    };    
    
    configuration.add(<span class="code-quote">"rule1"</span>, rule1);
    configuration.add(<span class="code-quote">"rule2"</span>, rule2, <span
class="code-quote">"after:rule1"</span>);
    configuration.add(<span class="code-quote">"rule3"</span>, rule3, <span
class="code-quote">"after:rule2"</span>);
    configuration.add(<span class="code-quote">"rule4"</span>, rule4);
    
}

</pre>
</div></div>

<p>This examples shows the URL rewriting chaining: the first rule rewrites requests
to <tt>/struts</tt> and rewrites them to <tt>/jsf</tt> and leaves
requests to other URLs unchanged. The second rewrites <tt>/jsf</tt> to <tt>/tapestry</tt>
and the third rewrites <tt>/tapestry</tt> to <tt>/urlrewritesuccess</tt>.</p>

<p>The result is that any request to <tt>/struts</tt> end up being handled
by the same class that handles <tt>/urlrewritesuccess</tt>, while the browser,
the user and Tapestry still sees <tt>/struts</tt>.</p>

<p>Note that this applies to rewriting links generated by Tapestry too: a <tt>PageLink</tt>
to the <tt>urlrewritesuccess</tt> page with an activation context of <tt>login</tt>
(path <tt>/urlrewritesuccess/login</tt>) will generate an <tt>a</tt>
tag pointing to <tt><a href="http://login.domain.com" class="external-link" rel="nofollow">http://login.domain.com</a></tt>.</p>

<p>The URLRewriteContext (added in 5.1.0.4) provides additional information for rewriting,
particularly in the context of rewriting generated link urls. In the following example, we'll
reconfigure the url used to render pages. Whereas the previous examples used separate rules
for handling inbound and outbound rewriting, this demonstration will utilize a single rule
for both scenarios. To simplify the example, we will assume that every page is named "XXXPage"
(UserPage, TransactionPage, IndexPage, etc.). This naming convention also means that we don't
have to worry about tapestry's auto-stripping of "index" from urls, because our page would
be IndexPage, rather than Index.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

<span class="code-keyword">public</span> <span class="code-keyword">static</span>
void contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
{
    URLRewriterRule rule = <span class="code-keyword">new</span> URLRewriterRule()

    {
        <span class="code-keyword">public</span> Request process(Request request,
URLRewriteContext context)
        {
            <span class="code-keyword">if</span> (context.isIncoming())
            {
                <span class="code-comment">//these look like component event requests,
which we didn't rewrite, so ignore.
</span>                <span class="code-keyword">if</span> (request.getPath().contains(<span
class="code-quote">"."</span>) || request.getPath().contains(<span class="code-quote">":"</span>))

                {
                    <span class="code-keyword">return</span> request;
                }
                <span class="code-object">String</span> pageName = request.getPath().substring(1,request.getPath().indexOf('/',1));
                <span class="code-keyword">return</span> <span class="code-keyword">new</span>
SimpleRequestWrapper(request, request.getPath().replaceAll(pageName,pageName + <span class="code-quote">"page"</span>));
            }
            <span class="code-keyword">else</span>
            {
               <span class="code-comment">//<span class="code-keyword">if</span>
<span class="code-keyword">this</span> is a component event, getPageParameters()
will <span class="code-keyword">return</span> <span class="code-keyword">null</span>.
</span>               <span class="code-keyword">if</span> (context.getPageParameters()
!= <span class="code-keyword">null</span>) 
               {
                    <span class="code-object">String</span> path = request.getPath();
                    <span class="code-object">String</span> pageName = context.getPageParameters().getLogicalPageName().toLowerCase();
                    <span class="code-object">String</span> newPageName = pageName.replaceAll(<span
class="code-quote">"page$"</span>,"");
                    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
SimpleRequestWrapper(request,path.replaceAll(pageName,newPageName));
               }
            }
            <span class="code-keyword">return</span> request;
        }

        <span class="code-keyword">public</span> RewriteRuleApplicability applicability()
        {
            <span class="code-keyword">return</span> RewriteRuleApplicability.BOTH;
        }
    };

    configuration.add(<span class="code-quote">"rule1"</span>,rule);

}

</pre>
</div></div>

<p>In the first part of <tt>process</tt>, <tt>context.isIncoming()</tt>
determines if the call to <tt>process</tt> occured due to an inbound request.
If so, the rule reverses the mapping done in the second portion of the method, so tapestry
sees the original request.</p>

<p>The second half of <tt>process</tt> rewrites only page links by retrieving
the logical page name and replacing its occurence in the url with the shortened form of the
link. This code segment demonstrates how the additional information provided by <tt>URLRewriteContext</tt>
can be used to rewrite urls in a generalized manner.</p>

<p>Note that <tt>getPageParameters()</tt> will only return non-null when
<tt>process</tt> is called due to page link creation, and <tt>getComponentEventParameters()</tt>
will only return non-null when <tt>process</tt> is called as a result of creating
component event links.</p>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/TAPESTRY/URL+rewriting">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=22872143&revisedVersion=2&originalVersion=1">View
Changes</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message