I have 2 liferay+springmvc portlet applications (2 war files).
First portlets is Category portlet which lists all the available categories. When a category link is clicked i will display products(default page) page with list of products from the selected category in portlet-2. I am communicating the selected category via PortletSession.
In portlet-2, user can add products to cart and navigate to cart page(which is also in portlet-2).
Now if user clicks another category on portlet-1 then I wan to display products(default) pages. But currently what is happening is when a category link is clicked on portlet-1 then cart page is re-rendered because cart page is active now on portlet-2, which is expected.
@Controller
@RequestMapping("VIEW")
public class CatalogListingPortlet {
@Autowired
private CategoryRepository categoryRepository;
@RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, Model model) {
model.addAttribute("categories", categoryRepository.findAll());
return "categories";
}
@ActionMapping(params = "action=showCategory")
public void showCategory(ActionRequest request, ActionResponse response) {
String categoryId = ParamUtil.get(request, "categoryId",StringPool.BLANK);
request.setAttribute("categoryId", categoryId);
PortletSession portletSession = request.getPortletSession();
portletSession.setAttribute("LIFERAY_SHARED_categoryId", categoryId, PortletSession.APPLICATION_SCOPE);
}
}
@Controller
@RequestMapping("VIEW")
public class ProductListingPortlet
{
@Autowired
private CategoryRepository categoryRepository;
@Autowired ProductRepository productRepository;
@RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, Model model) {
PortletSession portletSession = request.getPortletSession();
String categoryId = (String) portletSession.getAttribute("LIFERAY_SHARED_categoryId", PortletSession.APPLICATION_SCOPE);
Category category = categoryRepository.findOne(Long.parseLong(categoryId));
List<Product> products = category.getProducts();
portletSession.setAttribute("PRODUCTS", products);
return "products";
}
@ActionMapping(params = "action=addProductToCart")
public void addProductToCart(ActionRequest request, ActionResponse response) {
//logic to add the selected product to cart
}
@RenderMapping(params = "action=checkout")
public String checkout(RenderRequest request, RenderResponse response, Model model) {
return "checkout";
}
}
When user clicks on a category link in portlet-1 then I want to invoke @RenderMapping method in portlet-2.
To be specific from CatalogListingPortlet.showCategory() method I need to trigger ProductListingPortlet.handleRenderRequest() method.
How can I do it?
You can send data between portlets through IPC (Inter Portlet Communication):
In CatalogListingPortlet:
@ActionMapping(params = "action=showCategory")
public void showCategory(ActionRequest request, ActionResponse response) {
QName qname = new QName("http://liferay.com/events","ipc.messsage","x");
response.setEvent(qname, "some message");
}
In ProductListingPortlet:
@EventMapping(value ="{http://liferay.com/events}ipc.messsage")
public void receiveEvent(EventRequest request, EventResponse response) {
Event event = request.getEvent();
String messsage = (String)event.getValue();
//process the message
}
Configuration in portlet.xml:
<portlet>
<portlet-name>catalogListingPortlet</portlet-name>
...
<supported-publishing-event>
<qname xmlns:x="http://liferay.com/events">x:ipc.messsage</qname>
</supported-publishing-event>
</portlet>
<portlet>
<portlet-name>productListingPortlet</portlet-name>
...
<supported-processing-event>
<qname xmlns:x="http://liferay.com/events">x:ipc.messsage</qname>
</supported-processing-event>
</portlet>
<event-definition>
<qname xmlns:x="http://liferay.com/events">x:ipc.messsage</qname>
<value-type>java.lang.String</value-type>
</event-definition>