1
votes

I've created a Spring MVC portlets project and I'm trying to implement IPC between two of my portlets (SenderPortlet and ConsumerPortlet). Everything works fine but I need to initialize a bean model that I put in session so I've used SessionAttributes annotation and ModelAttribute annotation on the method that initialize the bean. I have two states:

  • Before putting ModelAttribute annotation: Everything works fine. I mean IPC.
  • After putting ModelAttribute annotation: An exception is thrown when I click on the action that fire the IPC sender event: org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public void com.test.SenderController.myAction(org.springframework.web.bind.support.SessionStatus,javax.portlet.ActionResponse)]; nested exception is java.lang.IllegalStateException: Current request is not of type [javax.portlet.RenderRequest]: com.liferay.portlet.ActionRequestImpl@127e27ff

Note that myAction is the method on which the action is mapped. This methd sets the IPC event. Here is its signature:

@ActionMapping("action") public void myAction(SessionStatus status, ActionResponse response) { // some code... }

I can not understand why this exception is fired since I add the modelAttribute annotation.

Can you please help me on this ?

Many thanks.

regards,

EDIT 1 More code

ConsumerPortlet.java

@Controller(value = "ConsumerPortlet")
@SessionAttributes( value="products" )
@RequestMapping("VIEW")
public class ConsumerPortlet {

@RequestMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, Model model) {
    try {
        //some code       
    return "page";
}

@ModelAttribute("products")
public List<ProductBean> initilizeProduct(RenderRequest renderRequest){

   //some  code
    return productList;
}


 @EventMapping(value ="{http://liferay.com/events}myEvent")
 public void processEvent(EventRequest request, EventResponse response) throws PortletException, IOException {
 javax.portlet.Event event = request.getEvent();
         String testValue = (String) event.getValue();
        System.out.println("IPC test value: "+testValue);
 }

SenderPortlet.java

@Controller(value = "SenderPortlet")
@SessionAttributes( value="products" )
@RequestMapping("VIEW")
public class SenderPortlet {

@RequestMapping
public String handleRenderRequest(RenderRequest request,
        RenderResponse response, Model model) {
    return "page2";
}
    @ModelAttribute("products")
public List<ProductBean> initilizeProduct(RenderRequest renderRequest){
      PortletSession ps = renderRequest.getPortletSession();
        List<ProductBean> productList = (List<ProductBean>) ps.getAttribute("products",PortletSession.APPLICATION_SCOPE);
    return productList;
}

 @ActionMapping("myAction")
 public void myAction(SessionStatus status,
         ActionResponse response)
  {
    QName qname = new QName("http://liferay.com/events", "myEvent", "x");
    response.setEvent(qname, "test-value sent");
    status.setComplete();
   }

portlet.xml

    <portlet>
    <portlet-name>sender</portlet-name>
    <portlet-class>
        org.springframework.web.portlet.DispatcherPortlet
    </portlet-class>
    <init-param>
        <name>contextConfigLocation</name>
        <value>/WEB-INF/sender-portlet.xml</value>
    </init-param>
    <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>view</portlet-mode>
    </supports>
    <portlet-info>
        <title>Sender</title>
    </portlet-info>
    <supported-publishing-event>
       <qname xmlns:x="http://liferay.com/events">x:myEvent</qname>
    </supported-publishing-event>
</portlet>
<portlet>
    <portlet-name>consumer</portlet-name>
    <portlet-class>
        org.springframework.web.portlet.DispatcherPortlet
    </portlet-class>
   <init-param>
    <name>contextConfigLocation</name>
    <value>/WEB-INF/consumer-portlet.xml</value>
</init-param>
    <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>view</portlet-mode>
    </supports>
    <portlet-info>
        <title>Consumer</title>
    </portlet-info>       
    <supported-processing-event>
        <qname xmlns:x="http://liferay.com/events">x:myEvent</qname>
    </supported-processing-event>
</portlet>
<event-definition>
    <qname xmlns:x="http://liferay.com/events">x:myEvent</qname>
    <value-type>java.lang.String</value-type>
</event-definition>

liferay-portlet.xml

<portlet>
   <portlet-name>sender</portlet-name>
  <icon>/icon.png</icon>
  <instanceable>true</instanceable>
  <header-portlet-css>/css/test.css</header-portlet-css>
  <footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
   </portlet>
<portlet>
   <portlet-name>consumer</portlet-name>
   <icon>/icon.png</icon>
   <instanceable>true</instanceable>
   <header-portlet-css>/css/test.css</header-portlet-css>
   <footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
</portlet>

Liferay 6.2.10.12 Spring 3.0.7.RELEASE

1
It doesn't look like this is IPC related in any way - rather a wiring problem for the action handler of your portlet? Please post more code - e.g. more of the portlet class that exposes this question.Olaf Kock
@OlafKock I've updated the post.. Thanksjavaxiss

1 Answers

0
votes

As the method expecting the RenderRequest instead of ActionRequest, it is throwing that error. The below code might solve the problem or you can use generic Reuqest/Response i.e PortletRequest and PortletResponse

public void myAction(@ModelAttribute("products") List<ProductBean> productList, SessionStatus status,
         ActionResponse response)
  {
    QName qname = new QName("http://liferay.com/events", "myEvent", "x");
    response.setEvent(qname, "test-value sent");
    status.setComplete();
   }