Results 1 to 6 of 6

Thread: Spring Portlet MVC 3.0 M1 - eventing issue

  1. #1

    Default Spring Portlet MVC 3.0.0 M2 - eventing issue

    hi all,

    i am trying out eventing with Spring Portlet MVC 3.0 and i'm stuck; i keep getting
    Code:
    WARN  org.springframework.web.portlet.DispatcherPortlet  - Handler execution resulted in exception - forwarding to resolved error view
    javax.portlet.UnavailableException: No matching handler method found for portlet request: mode 'view', phase 'EVENT_PHASE', parameters map['actionException' -> array<String>['javax.portlet.UnavailableException: No matching handler method found for portlet request: mode 'view', phase 'EVENT_PHASE', parameters map['actionException' -> array<String>['javax.portlet.UnavailableException: No matching handler method found for portlet request: mode 'view', phase 'EVENT_PHASE', parameters map[[empty]]']]']]
    	at org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter$PortletHandlerMethodResolver.resolveHandlerMethod(AnnotationMethodHandlerAdapter.java:425)

    However, my controller implements handleEventRequest(EventRequest eventrequest, EventResponse eventresponse) of the EventAwareController interface ...

    Is this a known issue or am i implementing events the wrong way or .... ?

    Thanks in advance for any help ...
    - jeroen
    Last edited by jayrex; Apr 10th, 2009 at 08:50 AM. Reason: error in title

  2. #2

    Default

    adding the annotation @RequestMapping did the trick


  3. #3
    Join Date
    Jun 2009
    Posts
    19

    Default Spring Portlet MVC 3.0.0 M2 - eventing issue

    I am stuck too ...

    I should use @RequestMapping ? or @EventMapping ?

    does it takes any parameters too ?

    how do I set parameters in actionResponse.setEvent() ?

    thx
    Srinivas Chamarthi

  4. #4

    Default

    Use the appropriate annotation for the method you want to use for that particular phase;
    @RenderMapping
    @ActionMapping
    @EventMapping

    They take parameters
    e.g. @ActionMapping(params = 'param1=value1')

    @EventMapping takes a QName, make sure it is the same as defined in your portlet xml

    Don't forget to annotate the controller class with @Controller

    If you want to use eventing, you set the event in the action method of the portlet that triggered the event. In the event method of the other portlet(s) you get the event and use the payload as you wish.

    Anyway, i don't know if i understand your question fully.
    Google will help you further.

  5. #5
    Join Date
    Sep 2009
    Location
    Hannover
    Posts
    1

    Default Is eventing handled correctly in 3.0.M4

    Hi,
    I ran into the same issue with Spring 3.0.M4 and debugged it to see what is happening.
    I cannot image that what I found is intended to be.

    Image the situation having 2 Portlets (A and B) and 3 controllers:
    1. Controller will trigger the event (Portlet A):
    Code:
    @Controller
    @RequestMapping("VIEW")
    public class TriggerController {
    
        @RequestMapping
        protected void action(ActionRequest request, ActionResponse response) {
            
            response.setEvent("searchCommand", searchCommand);
    
        }
    }

    2. Controller will handle the event and the default render request (Portlet B):
    Code:
    @Controller
    @RequestMapping("VIEW")
    public class EventController {
    
        @EventMapping("searchCommand")        
        public void doSearch(EventRequest request) {
                //do something with the event
    
        }
        
        @RequestMapping
            public String renderDefault(RenderRequest request, Model model) {
               return "myPage";
            }
    }
    3. Controller will handle the render request for "action=details" (Portlet B):
    Code:
    @Controller
    @RequestMapping("VIEW")
    public class DetailsController {
        
        @RequestMapping(params = "action=details")
        public String renderDetails(ActionRequest request, ActionResponse response, Model model) {
        	
        	return "details";            
    
        }
        
    }
    The jsp "myPage.jsp" has a link to go to the details page:
    Code:
    	<a href="<portlet:renderURL><portlet:param name="action" value="details"/></portlet:renderURL>">go to Details</a>
    Step 1: The link on myPage is clicked and the DetailsControllers renderDetails method is executed.
    Step 2: The action of the TriggerController is requested and triggers the event.

    One might image that the EventController is executed, because it's the only one which can handle this event.
    But actually the following is happening:

    Step 3: The DefaultAnnotationHandlerMapping tries to determine the correct controller for Portlet B to be executed and ends up in this method:
    Code:
    protected Object getHandlerInternal(PortletRequest request) throws Exception {
    		K lookupKey = getLookupKey(request);
    		Object handler = this.handlerMap.get(lookupKey);
    		if (handler != null && logger.isDebugEnabled()) {
    			logger.debug("Key [" + lookupKey + "] -> handler [" + handler + "]");
    		}
    		if (handler instanceof Map) {
    			Map<PortletRequestMappingPredicate, Object> predicateMap =
    					(Map<PortletRequestMappingPredicate, Object>) handler;
    			List<PortletRequestMappingPredicate> predicates =
    					new LinkedList<PortletRequestMappingPredicate>(predicateMap.keySet());
    			Collections.sort(predicates);
    			for (PortletRequestMappingPredicate predicate : predicates) {
    				if (predicate.match(request)) {
    					predicate.validate(request);
    					return predicateMap.get(predicate);
    				}
    			}
    			return null;
    		}
    		return handler;
    	}
    At first it gets all the handler for the lookupKey, which is the portlets mode ("VIEW" in this case). It will continue with both the EventController and the DetailsConrtoller.
    In the next step it tries to determine the right one of the found handlers. Therefore the request parameters are evaluated. Since the portlet request has not changed on its own the request parameter is still "action=details".
    This will end up in the decision that the DatailsController is the correct one.

    Step 4: At this point the DatailsController is chosen to handle the request, which actually is an Event.
    Therefore Spring tries to find the method to be invoked to handle the event, Since the DetailsController has no "@EventMapping", there is no method found.
    This finally ends up in the exception:
    Code:
    javax.portlet.UnavailableException: No matching handler method found for portlet request: mode 'view', phase 'EVENT_PHASE', parameters map['org.springframework.web.portlet.mvc.ImplicitModel' -> array<String>['true'], 'action' -> array<String>['details']]
    Is this the intended behavior??

    If so, I can only think of two workarounds:
    1. Implement an event handling method in each controller of the portlet, to avoid getting this excpetion. Respectively put all "@EventMapping" methods in a superclass for all controllers so that it can be handled.

    2. Alternatively one could implement all controller methods in one class. This might be acceptable for small portlets, but is not for us.

    Both workarounds are quite ugly in my opion.

    Can anyone think of something better or is this a bug in Spring???

    Thanks in advance.

  6. #6
    Join Date
    Jun 2011
    Posts
    2

    Default

    Hello,

    I am developing 2 portlets and at this moment and i am trying to communicate between them through events. I got the error:

    Code:
    [WARN ][org.springframework.web.portlet.DispatcherPortlet][1164][http-8080-2]: Handler execution resulted in exception - forwarding to resolved error view
    javax.portlet.UnavailableException: No matching handler method found for portlet request: mode 'view', phase 'EVENT_PHASE', parameters map[[empty]]
        at
    In the file portlet.xml i have:


    Code:
    <?xml version="1.0"?>
    
    <portlet-app
        version="2.0"
        xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    >
        <portlet>
    ....
                <supported-publishing-event>
                <qname xmlns:x="http://liferay.com/events">x:chooseCommunity</qname>
            </supported-publishing-event>
        </portlet>
            <portlet>
        ...
                <supported-processing-event>
                 <qname xmlns:x="http://liferay.com/events">x:chooseCommunity</qname>
                </supported-processing-event>
        </portlet>
    
            <event-definition>
                <qname xmlns:x="http://liferay.com/events">x:chooseCommunity</qname>
                <value-type>java.lang.String</value-type>
            </event-definition>
    
    </portlet-app>
    In the Controller A (Sender) i have:

    Code:
      @ActionMapping("communityChoosen")
        protected void handleCommunityChoosen(ActionRequest request, ActionResponse response)
                throws Exception {
    
            String communityChoosen = request.getParameter("communityId");
    
            QName qname = new QName("http://liferay.com/events","chooseCommunity");
            response.setEvent(qname, communityChoosen);
        }
    In the Controller B(Receiver) i have:

    Code:
      @EventMapping(value = "{http://liferay.com/events}chooseCommunity")
      public void receiveEvent(EventRequest request, EventResponse response, ModelMap map) {
          Event event = request.getEvent();
          String communityIdFromEvent = (String) event.getValue();
          map.put("communityIdFromEvent", communityIdFromEvent);
          response.setRenderParameter("communityIdFromEvent", communityIdFromEvent);
        }
    I tried to run the portlets with the debugger and everything is fine when the code of Controller A is exectuted, but the program never executes after that in the controler B the method receiveEvent. Anyone can help me or give a suggestion about what i am doing wrong?

    Best Regards,
    Miguel Alves

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •