IPC в Spring MVC портлетах

Я создал проект портлетов Spring MVC и пытаюсь реализовать IPC между двумя моими портлетами (SenderPortlet и ConsumerPortlet). Все работает нормально, но мне нужно инициализировать модель компонента, которую я поместил в сессию, поэтому я использовал аннотацию SessionAttributes и ModelAttribute для метода, который инициализирует компонент. У меня есть два состояния:

  • Перед тем как поставить аннотацию ModelAttribute: все работает нормально. Я имею в виду IPC.
  • После размещения аннотации ModelAttribute: возникает исключение, когда я нажимаю на действие, которое запускает событие отправителя IPC: 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

Обратите внимание, что myAction - это метод, с которым сопоставляется действие. Этот метод устанавливает событие IPC. Вот его подпись:

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

Я не могу понять, почему это исключение срабатывает, так как я добавляю аннотацию modelAttribute.

Не могли бы вы помочь мне в этом?

Большое спасибо.

С уважением,

РЕДАКТИРОВАТЬ 1 Больше кода

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 ответ

Поскольку метод, ожидающий RenderRequest вместо ActionRequest, он выбрасывает эту ошибку. Приведенный ниже код может решить проблему, или вы можете использовать общий Reuqest/Response, т.е. PortletRequest и 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();
   }
Другие вопросы по тегам