URLs in WebLogic Portal 8.1: A Tutorialby Subbu Allamaraju AbstractOne of the core responsibilities of the BEA WebLogic Portal 8.1 framework is to create URLs consistently and correctly so users can interact with various portlets within the context of a portal page. The purpose of this article is to show you the plumbing behind the URL creation process in WebLogic Portal. In this article, I will discuss how WebLogic Portal creates URLs, the different kinds of URLs that can be created, the APIs and layers behind URLs, and what happens to URLs when you offer or consume portlets using Web Services for Remote Portlets (WSRP). As we walk through the URL creation process, I will also highlight some best practices. After reading this article, you will be able to avoid most of the common pitfalls with URLs and be able to provide a consistent user experience with your portlets. The ProblemWhy is URL creation such a core responsibility of the WebLogic Portal? Why can't portlets create URLs just like you always create in HTML/JSP pages, as in the code sample below? Click <a href="next.jsp">here</a> to continue. When the user clicks on a link like this, one of the following things can happen:
To avoid these, portlets must let WebLogic Portal create URLs. There are several reasons why portlets should delegate this responsibility to WebLogic Portal: TIP: When you are creating portlets, do not assume anything about the structure of URLs. The actual structure is determined not only by the templates deployed in the portlet's web app but also by the Consumer, in the case of WSRP.
When you delegate URL creation to WebLogic Portal, it can shield portlets from things such as portal page URLs, domain names, and proxy servers. Portal administrators and deployers can control these details without breaking any URLs in portlets. If you are curious to see one way to create the above link (assuming that you are creating this link in a simple JSP portlet), here it is: Click <a href="<render:jspContentUrl contentUri="next.jsp"/>">here</a> to continue. Now let's examine the plumbing behind WebLogic Portal's URLs. URL TemplatesWebLogic Portal uses short URL snippets called "URL templates" to create URLs. These are not valid URLs and require further processing to be useful. To see what a URL template looks like, create a portal project, and check its WEB-INF directory. In this directory, you will notice a <url-template name="default">
{url:scheme}://{url:domain}:{url:port}/{url:path}?{url:queryString}{url:currentPage}
</url-template> to continue.
TIP: You can replace any of the optional tokens with known values. For example, if you know that you are never going to access portal pages over HTTPS, you can replace "url:scheme" with "http" in all the URL templates.
You will notice that this file lists not just one but several templates. Before discussing why several templates are required, let's look into the structure of a URL template. Anatomy of a URL TemplateA URL template is a URL with one or more tokens. The tokens are predefined by WebLogic Portal, and, in the case of remote portlets, by the WSRP 1.0 specification. Each token is enclosed within braces ( Each URL template can have one or more of the following tokens:
url:prefix token with the path prefix
value used to set up the proxy server.
The list of templates contained in the Types of URLsWebLogic Portal uses three kinds of URLs:
A bit later on we will discuss how you can create any of these types of URLs in your JSPs. Referring back to the Each The second section of this file defines one or more <jpf-url-templates> <url-template-ref type="action" name="jpf-action"/> <url-template-ref type="secure-action" name="jpf-secure-action"/> ... </jpf-url-templates> Using URL TemplatesWebLogic Portal provides a number of ways to use the URL templates defined in the previous section. Using URL Templates ExplicitlyYou can use <%
ResourceURL url = ResourceURL.createResourceURL(request, response);
url.setScheme("http");
url.setDomain("my.domain.com");
url.setPort(8001);
url.setPathPrefix("/static");
url.setTemplate("my-resource-template");
url.setPath("/images/my.jpg");
%>
<img src="<%=url.toString()%>"/>
This snippet uses a <img src="http://my.domain.com:8001/static/images/my.jpg"/>TIP: Make sure the URL template you are using has a token for the corresponding setter method. If not, WebLogic Portal will ignore the call to the setter. Note that the template must exist in the In place of <%@ taglib uri="render.tld" prefix="render" %>
<img src="<render:resourceUrl port="8001" template="default-complete"
scheme="http" domain="my.domain.com"
pathPrefix="/static" path="/images/my.jpg"/> "/>
Note that all the framework skeleton JSPs use the render tags to create links to window mode/state buttons, links to pages, and so on. Using URL Templates in PortletsWhen you use Page Flow and Struts tags to create forms, links, and so on in Page Flow and Struts portlets, those JSP tags delegate URL creation to WebLogic Portal through URL rewriters. These URL rewriters use URL templates specified by The portlet container in WebLogic Portal uses a similar approach for Java portlets. When you create <% PortletURL actionURL = renderResponse.createActionURL(); PortletURL renderURL = renderResponse.createRenderURL(); %> WebLogic Portal will use the URL templates of type "action" and "resource" respectively to generate string values of these two URLs. URLs in Remote PortletsWhen you consume remote portlets using WSRP, it is very important to make sure that markup returned by remote portlets refers to the portal (the WSRP Consumer). When the portlet is remote, the Consumer acts as the intermediary between the end user and the portlet deployed on the WSRP Producer. Often, the Producer may set up security policies that restrict direct end user access to resources deployed on the Producer. So, links created without using WebLogic Portal are more likely to fail when the portlets are remote. The WSRP 1.0 specification specifies two methods for URL creation, "producer writing" and "consumer rewriting." Let's briefly examine these two methods. Producer WritingThis method involves the following steps:
Of these three steps, the third step depends on how the WSRP Consumer is implemented. In the case of the WebLogic Portal as the Consumer, Producer URL writing involves these steps:
When the WebLogic Portal is set up as a Producer, it uses the URL templates, just as it does when portlets are used locally. The only difference is that it uses the templates sent by the Consumer instead of those deployed locally on the Producer. Here is an example. Let's assume that you deployed a Page Flow portlet using the following JSP: <%@ taglib uri="netui-tags-html.tld" prefix="netui"%> <netui:anchor action="next">Next</netui:anchor> When you consume this portlet in WebLogic Portal Consumer, it sends the following SOAP request to get the markup of this portlet: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<urn:getMarkup xmlns:urn="urn:oasis:names:tc:wsrp:v1:types">
<urn:portletContext>
<urn:portletHandle>portlet_1</urn:portletHandle>
</urn:portletContext>
<urn:runtimeContext>
<urn:userAuthentication>wsrp:none</urn:userAuthentication>
<urn:portletInstanceKey>portlet_1_2_1</urn:portletInstanceKey>
<urn:namespacePrefix>portlet_1_2_1</urn:namespacePrefix>
<urn:templates>
<urn:defaultTemplate>
http://localhost:7001/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType={wsrp-urlType}&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}
</urn:defaultTemplate>
<urn:blockingActionTemplate>
http://localhost:7001/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType=blockingAction&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}
</urn:blockingActionTemplate>
<urn:renderTemplate>
http://localhost:7001/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType=render&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}
</urn:renderTemplate>
<urn:resourceTemplate>
http://localhost:7001/consumer/resource?_windowLabel=portlet_1_2_1&
wsrp-urlType=resource&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}
</urn:resourceTemplate>
<urn:secureDefaultTemplate>
http://localhost:7002/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType={wsrp-urlType}&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}
</urn:secureDefaultTemplate>
<urn:secureBlockingActionTemplate><![CDATA[
https://localhost:7002/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType=blockingAction&wsrp-secureURL=true&
wsrp-url={wsrp-url}&wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}]]>
</urn:secureBlockingActionTemplate>
<urn:secureRenderTemplate><![CDATA[
https://localhost:7002/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType=render&wsrp-secureURL=true&wsrp-url={wsrp-url}&
wsrp-requiresRewrite={wsrp-requiresRewrite}&
wsrp-navigationalState={wsrp-navigationalState}&
wsrp-interactionState={wsrp-interactionState}&
wsrp-mode={wsrp-mode}&wsrp-windowState={wsrp-windowState}]]>
</urn:secureRenderTemplate>
<urn:secureResourceTemplate>
https://localhost:7002/consumer/resource?_windowLabel=portlet_1_2_1&
wsrp-urlType=resource&wsrp-secureURL=true&
wsrp-url={wsrp-url}&wsrp-requiresRewrite={wsrp-requiresRewrite}
</urn:secureResourceTemplate>
</urn:templates>
<urn:runtimeContext>
<urn:userContext xsi:nil="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<urn:markupParams>
<urn:secureClientCommunication>false</urn:secureClientCommunication>
<urn:locales>en-US</urn:locales>
<urn:mimeTypes>text/html</urn:mimeTypes>
<urn:mimeTypes>*/*</urn:mimeTypes>
<urn:mode>wsrp:view</urn:mode>
<urn:windowState>wsrp:normal</urn:windowState>
<urn:clientData>
<urn:userAgent>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
SV1; .NET CLR 1.1.4322; FDM)</urn:userAgent>
</urn:clientData>
<urn:markupCharacterSets>UTF-8</urn:markupCharacterSets>
</urn:markupParams>
</urn:getMarkup>
</soapenv:Body>
</soapenv:Envelope>
The main detail to notice in this request is the templates element. Before sending URL templates to any Producer, WebLogic Portal Consumer replaces all Consumer-specific tokens in URL templates, leaving only WSRP 1.0-specific tokens. It is the responsibility of the Producer to replace the WSRP 1.0-specific tokens. Note that the templates in the above message are broken among several lines for better readability. In response to the above SOAP request, a WebLogic Portal Producer would return the following response: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<urn:getMarkupResponse xmlns:urn="urn:oasis:names:tc:wsrp:v1:types">
<urn:markupContext>
<urn:mimeType>text/html; charset=UTF-8</urn:mimeType>
<urn:markupString><![CDATA[
<a href="http://localhost:7001/consumer/hello.portal?_nfpb=true&
_windowLabel=portlet_1_2_1&_pageLabel=hello_page_2&
wsrp-urlType=blockingAction&wsrp-url=&wsrp-requiresRewrite=&
wsrp-navigationalState=&
wsrp-interactionState=_action%3D%252Fhello%252FHelloWorld%252Fbegin&
wsrp-mode=&wsrp-windowState=">Next</a>
]]></urn:markupString>
<urn:locale>en-US</urn:locale>
<urn:requiresUrlRewriting>false</urn:requiresUrlRewriting>
</urn:markupContext>
</urn:getMarkupResponse>
</soapenv:Body>
</soapenv:Envelope>
TIP: WebLogic Portal Producer can store URL templates in the HTTP session, and therefore WebLogic Portal Consumer sends URL templates once per session.
Note that the Producer used the If you are interested in learning more about the contents of these SOAP messages, visit the OASIS WSRP TC home page, and download the latest version of the WSRP 1.0 Primer. Consumer RewritingIn this approach, the Consumer does not send URL templates, and it involves the following steps:
For the above sample portlet, the Producer would return the response: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<urn:getMarkupResponse xmlns:urn="urn:oasis:names:tc:wsrp:v1:types">
<urn:markupContext>
<urn:mimeType>text/html; charset=UTF-8</urn:mimeType>
<urn:markupString>Hello World
<a href="wsrp_rewrite?wsrp-urlType=blockingAction&wsrp-secureURL=false
&wsrp-interactionState=_action%3D%252Fhello%252FHelloWorld%252Fbegin/wsrp_rewrite">Begin
</a></urn:markupString>
<urn:locale>en-US</urn:locale>
<urn:requiresUrlRewriting>true</urn:requiresUrlRewriting>
</urn:markupContext>
</urn:getMarkupResponse>
</soapenv:Body>
</soapenv:Envelope>
Note that the Producer Writing or Consumer Rewriting?The main difference between these two methods of URL creation is the use of URL templates. The kind of templates that WebLogic Portal Consumer sends to Producers do not require further processing of the markup returned by the Producer. This method therefore performs better when the WebLogic Portal is used as a Consumer. WebLogic Portal Producers (simple as well as complex) are set up by default to use Producer writing for URL generation. You can change this to use Consumer rewriting by updating the ConclusionOne of my goals in this article was to point out why URL creation is critical to providing a consistent user experience. When you use WebLogic Portal-provided APIs and JSP tags, Page Flow or Struts tags, or Java Portlet API or tags, the URL creation process relies on URL templates. WebLogic Portal has the ability to consume locally deployed templates as well as templates sent by remote Consumers. These features are designed so all links created can be controlled by URL templates that can be adjusted declaratively without code changes. It is quite possible to reverse-engineer the structure of generated URLs and create links manually (that is, without using any WebLogic Portal APIs or tags). Such links may work in some limited situations but are likely to fail when deployment configuration changes or when you use WSRP. Here are some final guidelines. Always use the following to create links:
Use URLs created without these tags at your own discretion. Such URLs may not always work. References
Subbu Allamaraju is the driver behind portal federation, and in recent years, focusing on portal-related standards such as JSR286, JSR301 and WSRP. Return to dev2dev. |
Tutorial Tools Related Products Check out the products mentioned in this article:Bookmark Tutorial
|