Search code examples
javaspringspring-mvcliferayliferay-6

How to call another portlet @RenderMapping method in liferay + springmvc?


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?


Solution

  • 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>