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();
}