URL Rewriting
1. Rationale
Traditionally, Web applications developers generate URLs in their Web pages
manually. For example, an HTML <a> element contains an
href attribute specifying the destination of a link. The default
PresentationServer Page Flow Controller epilogue contains a URL rewriting
mechanism for HTML and XHTML documents.
1.1 Servlets
Absolute URLs (starting with a scheme such as http:) are usually
reserved to refer to external sites or applications. When referring to the
current application, relative URLs, in the form of relative paths or absolute
paths, are commonly used. Developers must make sure that the URL interpreted by
the Web browser and the application server refers to the correct page or
resource:
-
Relative paths: such paths are interpreted by the Web browser as
relative to a URL base, usually the URL of the page being requested,
unless specified differently. For example, if a browser requests
/oxf/example1/page1:
Relative Path |
Resulting Absolute Path |
page2 |
/oxf/example1/page2 |
../page3 |
/oxf/page3 |
../example2/page4 |
/oxf/example2/page4 |
Using relative paths raises the issue that if a
page is moved, all the links within that page have
to be changed.
-
Absolute paths: such paths start with a "/". The developer can
generate the same paths as above by directly writing the resulting absolute
paths. The issue with this solution is that it is necessary to write the
exact absolute path, often including a J2EE Web applications context path
such as /oxf. Hardcoding the context path in every URL makes it
impossible to change the application context without changing all the URLs
in the application. To alleviate this issue, developers often use relative
URLs, with the problem mentioned above.
1.2 Portlets
The issue is even more important with Java Portlets (JSR-168), as URLs must be
generated by calling a specific Java API. With page template languages such as
JSP, this is done using tag libraries. All the pages in an application must be
modified when moved from a deployment as a Servlet to a deployment as a
Portlet.
A solution to the issues mentioned above is to post-process all URLs
to make the developer's life easier.
2. Default URL Rewriting
This section describes the default URL rewriting implementation in Presentation
Server. It is implemented in a pipeline called
oxf:/oxf/pfc/oxf-rewrite.xsl bundled within orbeon.jar. It is
referred to by the default epilogue under oxf:/config/epilogue.xpl,
the default error page under oxf:/config/error.xpl, as well as the JSF
epilogue example under oxf:/jsf/config/epilogue.xpl.
2.1 What is Rewritten?
The form, a, link, img, and
input elements are rewritten. In addition, their XHTML counterparts
in the http://www.w3.org/1999/xhtml namespace are also rewritten.
URLs can be parsed by the rewriting algorithm, so developers have to make sure
that they are well-formed. Absolute URLs (with a scheme) are left unmodified.
The special case of URLs starting with a query string (e.g.
?name=value) is handled. This last syntax is supported by most Web
browsers and because of its convenience, it is supported by the default
rewriting algorithm as well.
2.2 Servlets
Element / Attribute |
Action |
form/@action |
If the URL is a relative path, it is left unchanged. If the URL is an
absolute path, the context path is pre-pended. Absolute URLs are left
unchanged.
|
a/@href |
link/@href |
img/@src |
input[@type='image']/@src |
script/@src |
2.3 Portlets
Element / Attribute |
Action |
form/@action |
Rewritten to an action URL using the Portlet API method
RenderResponse.createActionURL(). The resulting URL
results in an action URL targeting the current portlet. Absolute URLs
are left unchanged.
|
form/@method |
If no form/@method is supplied, an HTTP POST
is forced, because the Portlet specification recommends submitting
forms with POST. If a method is supplied, the method is
left unchanged.
|
a/@href |
Rewritten to a render URL using the Portlet API method
RenderResponse.createRenderURL(). The resulting URL
results in a render URL targeting the current portlet. Absolute URLs
are left unchanged.
|
img/@src |
Rewritten to a resource URL encoding. The resulting URL points to a
resource within your Web application. Absolute URLs are left unchanged.
|
input[@type='image']/@src |
script/@src |
link/@href |
script and SCRIPT |
In text within those elements or their XHTML counterparts in the
http://www.w3.org/1999/xhtml namespace, occurrences of the
string wsrp_rewrite_ are replaced with the Portlet
namespace as obtained by the Portlet API method
RenderResponse.encodeNamespace(null).
|
3. Working with URL Rewriting
In PresentationServer, URLs come from two different sources:
-
Within XSLT templates, for example single pages or a theme stylesheet. This is
the case for most URLs, including links to resources (images, CSS stylesheets,
JavaScript files, etc.), links to other pages, etc.
-
Within an XForms' submission-info element, to specify the action
to be called when a form is submitted.
In both cases, URLs are subject to the following sections.
3.1 Servlets
URLs can be written as relative paths as usual, but they can also be written as
absolute paths without concerns about the context path. For example:
Initial Path |
Resulting Path |
/example1/page2 |
/oxf/example1/page2 |
/page3 |
/oxf/page3 |
/example2/page4 |
/oxf/example2/page4 |
3.2 Portlets
With Portlets, the benefit is even greater. Write your URLs as you would in a
regular Servlet-based application, and the rewriting pipeline takes care of
calling the Portlet API to encode the URLs. Since portlets do not have the
concept of path, URL paths are encoded as a special parameter named
oxf.path. Relative paths are resolved against the current path. The
following table illustrates action URL and render URL rewriting:
Initial Path |
Resulting Portlet Parameters |
/example1/page1?name1=value1&name2=value2 |
- oxf.path=/example1/page1
- name1=value1
- name2=value2
|
?name1=value1&name2=value2 |
- name1=value1
- name2=value2
|
Assuming the current value of oxf.path is /example1/page1:
../example2/page2?name1=value1&name2=value2
|
- oxf.path=/example2/page2
- name1=value1
- name2=value2
|
The following table illustrates resource URL rewriting:
Initial Path |
Resulting Path |
/path/to/my/image.gif?scale=100
|
/oxf/path/to/my/image.gif?scale=100
|
Assuming the current value of oxf.path is /example1/page1:
my/image.gif?scale=100
|
/oxf/example1/my/image.gif?scale=100
Note that using resource URLs relative to an PresentationServer Portlet
path (as handled by PresentationServer) does not necessarily make sense
unless you define your hierarchy of resources carefully.
|
4. Customizing URL Rewriting
There are multiple reasons why the default PresentationServer URL rewriting may
need to be modified, including:
- Supporting markup languages other than HTML and XHTML
-
Gaining more control over action URLs and render URLs in Portlets. The current
schema considers that only HTML and XHTML form elements generate actions.
Modifying the default behavior allows you to enable some or all hyperlinks to
generate actions URLs.
To implement your own URL Rewriting, you can either:
-
Modify your Page Flow Controller epilogue to no longer point to the default
oxf-rewrite.xpl and implement your own rewriting algorithm, either
directly in the epilogue or in a stylesheet, pipeline or processor pointed to by
your epilogue.
-
Use oxf-rewrite.xsl as a starting point. To do this, extract
oxf-rewrite.xsl from orbeon.jar and make a local copy
in your resource directory. Make sure your epilogue points to your version of
the rewriting pipeline. Modify your copy according to your needs.
5. Known Limitations
5.1 Portlets
-
The input document should not contain:
- Elements and attribute containing the string wsrp_rewrite
- Namespace URIs containing the string wsrp_rewrite
- Processing instructions containing the string wsrp_rewrite
-
It is not possible to specify:
- A destination portlet mode
- A destination window state
- A secure URL