Inter Portlet Communication (IPC) always seems quite tricky if you take a look at the forums. I have to admit, before WebCenter PS3 setting up IPC was quite a hassle.
Since the release of PS3 IPC has been made simple. No longer are we required to configure page parameters. Portlets are wired automatically when they have a parameter with the same name. The same goes for events.
I already made an overview of the new features of the portlets in PS3 so I will not repeat myself.
In this post I will show these features by using a simple example so you know how to apply them.
In my WebCenter 11g PS3 Tutorial I will also dedicate some sections on portlets and IPC so you will also be able to use these example to learn more about IPC.
You can download the sample application that i will explain here.
The producer has 2 portlets:
As you can see, the producer is not high tech but it shows exactly what you need to know in order to pass parameters from one portlet to another.
If you have worked with JSR 168 and WebCenter before you know that we needed to configure the parameters for IPC in the oracle-portlet.xml which is an extension on the portlet.xml. This is no longer needed. JSR 286 provided a way to configure parameters and assign them to portlets. All the techniques for setting and getting the values of those parameters are now included in the portlet standard.
So let's take a look at our portlet.xml:

As you can see, we have two portlets.
The parameters need to be set in the parameters section of the portlet.xml. In this section we specify all the parameters that the provider will use.

In the source code of the portlet.xml you will add following code for the parameter:
These parameters need to be assigned to portlets: This can be done in the parameters tab of a portlet:

In the source code of the portlet.xml you will see following code added to the portlet section:
This is also done for the ReceivingLocation portlet because that portlet also used the parameter. It's important to know that you need to assign the parameter to all the portlets who want to use the parameter. Whether to set or get the value.
This is all you need to do to configure the portlets.
Once we have configured the portlet.xml we need to write some code in our portlet that will set and/or get the value of that parameter.
In the LocationPortlet we set the value. This can be found in the LocationBean.java in the selectLocation method which is triggered by a click on a commandLink button on the view.jspx:
As you can see, this is not that difficult. Setting the parameter is do on the ActionResponse. You have to make sure that the name you provide matched the name of the parameter as defined in the portlet.xml.
That's it...
In the ReceivingLocation portlet we will get the value that has been set by the LocationPortlet. The code for this can be found in the ReceiveLocation.java class in the getLocation method
Getting the value is also quite easy. In stead of the ActionResponse we use the PortletRequest to retreive the value.
So as you can see from this code, we don't need to any code that will notify a portlet. The JSR 286 standard takes care of this. This is because both portlets are configured to use the parameter. This means that when one portlet changes the value of a parameter, these values will be passd thru to other portlets so they can request the new values. Quite nifty framework, don't you think?
People who worked with WebCenter PS2 or earlier versions and JSR 168 know that when you want to implement inter portlet communication, you need to define page parameters and bind the parameters to the portlet parameters and so on. If i would describe this procedure here, it would take me a few pages.
Luckely for us, all these things are no longer needed since WebCenter PS3 which is very good news.
When you want to consume these 2 portlets you only need to register the producer with your portal, drop the portlets on your page and that's it. Really... Nothing more to it. You don't even need to set a partialTrigger. All these things are handled automatically by WebCenter.
So i'll repeat myself: just drag and drop both portlets on the page and that's it. No additional configuration needed!
To be honnest, I am very pleased with this new way of working. We can make use of a nice interface to configure the portlet.xml and add parameters. We no longer need to configure page parameters in our consuming application. It's all done by WebCenter.
However, it's not all good... Well, that depends on how you develop your portlets. I as a dedicated Oracle developer i use ADF a lot and i want to make use of the ADF framework to build portlet because I really love business components and the rich components from ADF. However, there is a catch behind all this. ADF is very user friendly and uses a lot of partial page rendering (AJAX). When you are using portlets and you want to set a public render parameter, this can not be done in a partial submit. You need to submit the complete page in order to get a reference to the ActionResponse or PortletRequest.
This means that, for example you want to build a master portlet and a detail portlet. In ADF it is common that you update the detail when you select a new row. This is all handled by partial page rendering. Because of this, it is really not easy to set the parameter of your portlet because you always need a full submit. Therefore you should use a select button like the one i used in this example.
If someone should know how to set a parameter when you just select a row in a table, please be my guest and explain it. I would really love to know this.
Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer
Comments
Consuming the Portlets
Is there any reason the display would be different each time the consuming page is refreshed? Sometimes neither portlet is displayed, sometimes it's one, and sometimes it's the other. rarely do both appear at the same time.. it's quite frustrating!
I noticed this kind of
I noticed this kind of behavior on systems that are to weak to handle webcenter. Especially if you are trying to run the portlets on the same machine as your app is deployed. With a fast machine and lots of ram, this issue almost never occurs.
Thanks for the reply. I don't
Thanks for the reply. I don't know if it's the machine, the machine itself is 24Gb ram & 6 core/12 threads. I have the WLS tweaked a bit to increase the memory , permgen sizing, and GC.
I did see much better performance after the WLS updates. Now, after a few initial refreshes, the portlets are pretty steady.
I am still seeing a double refresh issue, but I bet it has something to do with the way I implemented the portlets on the consuming app. Here's a link to the Oracle forum thread: http://tinyurl.com/WCPortalHelp
I didn't want to come direct to you on this, but I do appreciate any insight you can offer! :)
Parameter is not Passing
I have created my own portlets that retrieve a value from a selected grid row and then passes it to many other portlets through the use of a shared public parameter. I am using your code almost line for line, but the value is not passing. I have verified that I am getting the right value from the grid before setting the parameter. But after I click on the select link, the second portlet never shows the new value. Do you have any idea why this might be happening?
set a parameter when you just select a row in a table,
Hi Yannick,
how about using clientlistener and serverlistener
we can use click event of table to call method in backing bean
have a button on jspx with actionlistener make it visible false.
use the method bind to serverlistener to programmatically call actionlistener of hidden button(submit the button) then using iterator binding get the required attribute from row and pass it to response.setRenderParameter
If the serverListener
If the serverListener triggers a full request instead of a partial I don't see a problem but my guess (I haven't tried it) is that this is handled by the ADF Controller as a PPR and therefore the request is partially which will not allow you to get a reference to the ActionResponse from the portlet because that's only possible in a full request.
If the serverListener
Hi Yannick,
but we are calling hidden button's actionlistener from serverlistener like:
RichCommandButton cb = this.cmdButtonCall ;
ActionEvent event2 = new ActionEvent(cb);
event2.queue();
in this case it will trigger full request and will call selectLocation like we call on normal button click
Sounds reasenable. I haven't
Sounds reasenable. I haven't tried it before so I would recommend trying it :)
If you get a classCastException when trying to access the ActionResponse you know it's not possible.
I'm just wondering what will happen with the JSF lifecycle or portlet lifecycle when you do it that way...
It sounds like an interesting thing to try...
Exception
I tried with this and it gives java.lang.ClassCastException.
when you submit some button from backing bean its DispatchResourceResponse
and when you actually click button on portlet its ActionResponse
As I predicted :)
As I predicted :)
These techniques are specific to ADF and do not support the proper portlet lifecycle.
Add new comment