Building PortletsBuilding Portletswith Ajax Behaviorwith Ajax Behavior
2
Topics
• Issues with Current Portlet Architecture • Work-around• Maintaining portlet state• Avoiding namespace collision• Next generation Portal server
Issues with CurrentIssues with CurrentArchitecture (for Architecture (for supporting Ajax) &supporting Ajax) &One work-aroundOne work-around
4
Issues with Current Portlet Architecture• No easy way to make asynchronous call• The response contains markup for the
whole page not just for the target portlet• Will be addressed in JSR 186
One Work-aroundOne Work-around
6
One Work-around
• Make an asynchronous call to Servlets and JSP that are bundled with the portlet> Because a portlet is a Web application that can
contain other resources, such as servlets and JSP pages
> The portlet and the servlet should be able to share information between themselves through their sesssion
> The Invoice Viewer sample includes a servlet that you can call to asynchronously render new content in the portlet
Maintaining Portlet StateMaintaining Portlet State
8
Sharing Portlet State
• When you dynamically update portlet content with an Ajax call to a servlet, how do you maintain the portlet's state? > The PortletSession must store all attributes in the
HttpSession of the portlet application. > A direct consequence of this is that data stored in
the HttpSession by servlets or JSPs is accessible to portlets through the PortletSession in the portlet application scope.
> Conversely, data stored by portlets in the PortletSession in the portlet application scope is accessible to servlets and JSPs through the HttpSession.
•
9
Saving Portlet State in HTTP Session in Servlet code• InvoiceServlet stores the invoicenumber
attribute in HttpSession when doPost() is asynchronously called by the portlet, as follows.> request.getSession().setAttribute(namespace +
".invoicenumber", invoice);
10
Retrieving Portlet State from HTTP Session in Portlet Code• Portlet's main JSP page (view.jsp) can
check for the invoicenumber attribute by calling getAttribute() on PortletSession, as follows.<% // Check for invoice in session. String invoice =
(String)renderRequest.getPortletSession().getAttribute(namespace +
".invoicenumber", PortletSession.APPLICATION_SCOPE);
%>
11
Information Sharing Between a Portlet and a Servlet
Using JavaScript LibraryUsing JavaScript Library
13
Using JavaScript in Portlet
• You can use many emerging JavaScript libraries and toolkits within a portlet's Web application> Dojo toolkit> Many more
14
Example: view.jsp<script type="text/javascript">
/* Use dojo.io.bind to asynchronously get invoice content. */function <portlet:namespace/>_loadInvoice(invoice) {
/* If an invoice was selected ... */ if (invoice != null && invoice != "null") {/* Put selected invoice value on query string. */var querystring = new Array();querystring['invoice'] = invoice;/* Set up bind arguments: *//* url: url for request *//* method: http method *//* content: key/value mapping of parameters sent with request *//* handle: function to run when there is a response *//* mimetype:mimetype of response */var bindArgs = { url: "<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/ InvoiceServlet")%>", method: "POST", content: querystring, handle: function(type, data, evt) {if (type == "error") { /* Swap returned error message */ data = "<p style='color:red'>" + data.message + "</p>";}/* Swap the returned data into the div tag. */var div = document.getElementById("<portlet:namespace/>_content");div.innerHTML = "";div.innerHTML = data; }, mimetype: "text/html"};dojo.io.bind(bindArgs); }};
Avoiding NamespaceAvoiding NamespaceCollisionsCollisions
16
Two Possible Areas of Namespacecollisions• Portlet namespace• Dojo namespace (or any other JavaScript
toolkit library)
17
Avoid Portlet Namespace Collision
• Each portlet window (from the same portlet) should have its own namespace> Use <portlet:namespace/>> Apply it to both functions and variables
• Example> <portlet:namespace/>_loadInvoice = function
(invoice) {> ...> <div id="<portlet:namespace/>_content"></div>
18
Dojo Namespace Collision Issue
• The sample bundles the Dojo JavaScript library in its WAR file and, once deployed, references that library. However, other portlets on the portal might also use Dojo, but Dojo allows only one top-level reference for its reserved namespace.
• Verify that it is not loaded by checking the namespace and dynamically loading the Dojo library only when it is absent.
• Subsequently, the script dynamically adds JavaScript on the client when the content is loaded.
19
Avoid Dojo Namespace Collision<div id="<portlet:namespace/>_main"><script type="text/javascript">
/* Load the Dojo library if it hasn't been loaded already. */if (typeof dojo == "undefined") { /* Build script tag. */ var script = document.createElement("script"); script.src =
"<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/js/dojo.js") %>"; script.type= "text/javascript"; /* Insert at the top of portlet main. */ var <portlet:namespace/>_main =
document.getElementById("<portlet:namespace/>_main"); <portlet:namespace/>_main.insertBefore(script,
<portlet:namespace/>_main.firstChild);}</script>
Next GenerationNext GenerationPortal Server Desktop withPortal Server Desktop withAjax SupportAjax Support
21
AJAX – Desktop Functional Overview
• Asynchronous loading of channels and portlets• Delegates aggregation to the client (via
AjaxTableContainer)• AJAXified container controls such as refresh, maximize,
minimize, and remove• Drag and drop positioning of channels• Support for multiple page layouts• Seamlessly support AJAX portlets developed in
NetBeans, using the NetBeans plugin• Integrate into PS 7.x as global level container provider
22
High Level Architecture
23
High Level Architecture
DOJO Javascript Library
sunportal.AJAXRequest
sunportal.AJAXTableContainer
sunportal.AJAXChannel
Browser
AJAXTableContainerProvider
AJAXEditContainerProviderHTML
JSON
Portal (Enterprise Sample)
JSON: Javascript Object Notation (www.json.org)
24
High Level Architecture• JSON: JavaScript Object Notation
> It is easy for humans to read and write. > It is easy for machines to parse and generate. > It is based on a subset of the JavaScript Programming
Language• JSON is built on two structures:
> A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
> An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
25
Design Constraints• The AJAX Container must meet the following
constraints:>The client browser is required to support Javascript
and have it enabled.>The AJAX Container will NOT automatically AJAX-
enable content within a channel/portlet. – It is the channel/portlet developer's responsibility
to incorporate AJAX functionality (if required) in the channel/portlet content.
>Edit pages of channels and portlets may have to be customized to appear properly in the inline edit box.
26
Client Side Library Design - Dojo• Open source DHTML Toolkit
written entirely in Javascript• Provides easy to use Event
system, DOM and I/O APIs• Ships with a small core that can
load packages as required• Sun is standardizing on Dojo as
AJAX library of choice• Javascript library provides more
flexibility in application design than hybrid frameworks such as DWR and GWT
27
Client Side Library Design
sunportal.AJAXTableContainerPagePreferences
sunportal.AJAXRequest
sunportal.AJAXChannel
JSON container model JSON channel model
• sunportal.AJAXTableContainer uses Dojo DOM API to construct portal page from the JSON container model
• All requests made using sunportal.AJAXRequest which uses Dojo I/O API
• Event system uses XHR Callback model to handle server responses
28
Desktop Server-Side Design• Desktop acts as a content service for the AJAX
client.> Requests are made via standard desktop URLs (e.g. provider=foobar&action=content)
> Responses are either:> HTML content> JSON messages
• Desktop defers aggregating the content to the client (container model).> Powerful performance implications> Aggregation can be half of used CPU cycles.
29
Desktop Server Design – Get Content
JSR-286 Effort onJSR-286 Effort onAjax SupportAjax Support
JSR-286: Ajax Support• Currently asynchronous rendering of portlets is not
currently mentioned in the Portlet Specification• AJAX (Asynchronous JavaScript technology and
XML) support is vendor specific• Difficult to get AJAX working for more than one portlet
on a page• State is updated without server roundtrip and thus the
state that may be encoded in other portlets may be stale
• Bypasses standard browser paradigms, like back button and reload.Lot of extra effort is required to get these paradigms working again in an AJAX application
Ajax and PortletAjax and Portlet
Sang ShinSang [email protected]@sun.comwww.javapassion.comwww.javapassion.comJava Technology ArchitectJava Technology Architect
Top Related