Foren

Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portlets

Manoj GT, geändert vor 11 Jahren.

Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portlets

Junior Member Beiträge: 26 Beitrittsdatum: 06.04.12 Neueste Beiträge
Hi,

I am developing Spring MVC based portlet in liferay. Basically I want to configure and maintain 2 or 3 portlets in a single liferay project itself. Can some on guide me with the configuration required for the same. Like config code for portlet.xml, spring config and web config (if its required). I just need to configure a default controller for all my portlets separately so each will land in different landing page.

Note: I am using annotation based development.

Regards,
Manoj-GT
thumbnail
Apoorva Prakash, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Liferay Master Beiträge: 658 Beitrittsdatum: 15.06.10 Neueste Beiträge
Hi Manoj,

If I'm understanding your problem correctly, you solution is multi portlet war.

You just have to put correct entries in XML, namely portlet.xml, liferay-portlet.xml and liferay-display.xml.

See the following:
portlet.xml

<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>
		<portlet-name>portlet1</portlet-name>
		<display-name>portlet1</display-name>
		<portlet-class>com.portlet.portlet1</portlet-class>
		<init-param>
			<name>view-jsp</name>
			<value>/html/portlet1/view.jsp</value>
		</init-param>
		<expiration-cache>0</expiration-cache>
		<supports>
			<mime-type>text/html</mime-type>
		</supports>
		<portlet-info>
			<title>portlet1</title>
			<short-title>portlet1</short-title>
			<keywords>portlet1</keywords>
		</portlet-info>
		<security-role-ref>
			<role-name>administrator</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>guest</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>power-user</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>user</role-name>
		</security-role-ref>
	</portlet>

<portlet>
		<portlet-name>portlet2</portlet-name>
		<display-name>portlet2</display-name>
		<portlet-class>com.portlet.portlet2</portlet-class>
		<init-param>
			<name>view-jsp</name>
			<value>/html/portlet2/view.jsp</value>
		</init-param>
		<expiration-cache>0</expiration-cache>
		<supports>
			<mime-type>text/html</mime-type>
		</supports>
		<portlet-info>
			<title>portlet2</title>
			<short-title>portlet2</short-title>
			<keywords>portlet2</keywords>
		</portlet-info>
		<security-role-ref>
			<role-name>administrator</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>guest</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>power-user</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>user</role-name>
		</security-role-ref>
	</portlet>	
</portlet-app>


liferay-portlet.xml
<liferay-portlet-app>
	<portlet>
		<portlet-name>portlet1</portlet-name>
		<icon>/images/icon.png</icon>		
		<instanceable>true</instanceable>
		<header-portlet-css>/css/main.css</header-portlet-css>
		<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
		<css-class-wrapper>portlet1</css-class-wrapper>
	</portlet>
	
	<portlet>
		<portlet-name>portlet1</portlet-name>
		<icon>/images/icon.png</icon>
		<instanceable>true</instanceable>
		<header-portlet-css>/css/main.css</header-portlet-css>
		<header-portlet-javascript>/js/main.js</header-portlet-javascript>
		<css-class-wrapper>portlet2</css-class-wrapper>
	</portlet>
</liferay-portlet-app>


and in liferay-display.xml

<display>
	<category name="category.sample">
                     <portlet id="portlet1" />
                     <portlet id="portlet2" />
        </category>
</display>


Hope this will help...

Thanks and Regards,
Apoorva Prakash
thumbnail
Jan Geißler, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Liferay Master Beiträge: 735 Beitrittsdatum: 05.07.11 Neueste Beiträge
This will definetly NOT suffice. You will have to do a lot more of setup.

First of all in your web.xml you should do the following:
<servlet>
    	<servlet-name>ViewRendererServlet</servlet-name>
    	<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
    	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    	<servlet-name>ViewRendererServlet</servlet-name>
    	<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>

Than in your portlet.xml you need to change he Class to DispatcherPortlet like this:

<portlet>
		<portlet-name>MessageAdmin</portlet-name>
		<display-name>MessageAdmin</display-name>
		<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
</portlet>


To follow the Example, here the Name of the POrtlet would be MessageAdmin. So you will need a file called :
MessageAdmin-portlet.xml looking like this:

<import resource="../context/common.xml" />
	<context:annotation-config />
	
	<context:component-scan base-package="de.osc.commons.web.controller.messageadmin"></context:component-scan>  

and in Common.xml I have all stuf all my portlets need. It looks like this:

	<context:component-scan base-package="de.osc.*">
		<context:exclude-filter type="regex" expression="de.osc.applicantdata.web.controller.*.*" />
		<context:exclude-filter type="regex" expression="de.osc.commons.web.controller.*.*" />			
	</context:component-scan>
	
	
	<!-- Our Database Driven Message Source -->
	<bean id="messageSource" class="de.osc.commons.service.messagesource.DatabaseMessageSourceImpl" />		
	
	
	
	<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping">
			<property name="interceptors">
			<!-- Console interceptor to display Feedback Messages -->
		  	<list>
                <ref bean="consoleInterceptor" />  
            </list>
    	</property> 
	</bean>
	
	<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="cache" value="true" />
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />

	</bean>

Take a deeper look at the lines whith the Exclude filter. This is Important or otherwise all Portlets will Instantiate all Controllers, and this really will give you unexpected results and Headaches ;)
Also I should point at the viewResolver, as it will specify the path where the JSP for your viewResolving will be. Hope this helps you to start ;)

So long
Jan
thumbnail
Apoorva Prakash, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Liferay Master Beiträge: 658 Beitrittsdatum: 15.06.10 Neueste Beiträge
Hey Jan,

Thanks for appending... I have a set of portlets working with the same specs...

But they don't have database connectivity... Will try it out.

Thanks and Regards,
Apoorva Prakash
Manoj GT, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Junior Member Beiträge: 26 Beitrittsdatum: 06.04.12 Neueste Beiträge
@Apoorva Prakash @Jan : Thanks for ur reply emoticon

Instead of giving a simple JSP page inside the init-param I want to give a controller name in it.

<init-param>
<name>view-jsp</name>
<value>/html/portlet1/view.jsp</value>
</init-param>

Basically I will be giving something like <value>defaultController</value> this. Where defaultController is my controller name which will render the view.jsp.

Do you know the value need to be passed for the <name> tag in this case?

Regards,
Manoj-GT
thumbnail
Jan Geißler, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl (Antwort)

Liferay Master Beiträge: 735 Beitrittsdatum: 05.07.11 Neueste Beiträge
Well, that's why you have this line in your portlet.xml:

 <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>


So all Requests made to this portlet will be intercepted by the DispatcherPortlet Class, which will "dispatch" ;) to your Controllers. Now you have the possibility to name your controller in your PortletName-portlet.xml via a <bean> declaration, or as you wanted to do it with annotations. For the Annotation approach you need to tell Spring where to find the controllers. This will be done via the

 <context:component-scan base-package="de.osc.*">
        <context:exclude-filter type="regex" expression="de.osc.applicantdata.web.controller.*.*" />
        <context:exclude-filter type="regex" expression="de.osc.commons.web.controller.*.*" />            
    </context:component-scan>


declaration. This declaration will scan all Classes within the package "de.osc" and all of it's subpages - but NOT the classes in "de.osc.applicantdata.web.controller" and "de.osc.commons.web.controller" all of their subpackages - for Annotations like "Component", "Controller" etc.
So you only have to Annotate your Controller with @Controller and @RequestMapping("view") to get the setup working.
Hope this helps ;)
Manoj GT, geändert vor 11 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Junior Member Beiträge: 26 Beitrittsdatum: 06.04.12 Neueste Beiträge
Thanks a lot emoticon I have successfully configured multiple portlets by the approach suggested by you.
Rahul Agarwal, geändert vor 9 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

New Member Beitrag: 1 Beitrittsdatum: 13.06.14 Neueste Beiträge
Hi Manoj,

I am also trying to do the exact same thing that you did. Though its very long time that you did this still I hope you can help me. I have configured as per the steps mentioned above but I'm getting following error:

ERROR [http-bio-8080-exec-85][render_portlet_jsp:132] null
java.lang.IllegalArgumentException: Object of class [org.springframework.web.portlet.context.PortletRequestAttributes] must be an instance of class org.springframework.web.context.request.ServletRequestAttributes

Regards,
Rahul
Manoj GT, geändert vor 9 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Junior Member Beiträge: 26 Beitrittsdatum: 06.04.12 Neueste Beiträge
Sorry Rahul. I was just out of the Liferay for some months so didn't check your post. Do you still need any help ?

Regards,
Manoj-GT
Ettore Giallaurito, geändert vor 10 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

New Member Beiträge: 7 Beitrittsdatum: 11.06.13 Neueste Beiträge
Jan Geißler:
This will definetly NOT suffice. You will have to do a lot more of setup.

First of all in your web.xml you should do the following:
<servlet>
    	<servlet-name>ViewRendererServlet</servlet-name>
    	<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
    	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    	<servlet-name>ViewRendererServlet</servlet-name>
    	<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>

Than in your portlet.xml you need to change he Class to DispatcherPortlet like this:

<portlet>
		<portlet-name>MessageAdmin</portlet-name>
		<display-name>MessageAdmin</display-name>
		<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
</portlet>


To follow the Example, here the Name of the POrtlet would be MessageAdmin. So you will need a file called :
MessageAdmin-portlet.xml looking like this:

<import resource="../context/common.xml" />
	<context:annotation-config />
	
	<context:component-scan base-package="de.osc.commons.web.controller.messageadmin"></context:component-scan>  

and in Common.xml I have all stuf all my portlets need. It looks like this:

	<context:component-scan base-package="de.osc.*">
		<context:exclude-filter type="regex" expression="de.osc.applicantdata.web.controller.*.*" />
		<context:exclude-filter type="regex" expression="de.osc.commons.web.controller.*.*" />			
	</context:component-scan>
	
	
	<!-- Our Database Driven Message Source -->
	<bean id="messageSource" class="de.osc.commons.service.messagesource.DatabaseMessageSourceImpl" />		
	
	
	
	<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping">
			<property name="interceptors">
			<!-- Console interceptor to display Feedback Messages -->
		  	<list>
                <ref bean="consoleInterceptor" />  
            </list>
    	</property> 
	</bean>
	
	<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="cache" value="true" />
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />

	</bean>

Take a deeper look at the lines whith the Exclude filter. This is Important or otherwise all Portlets will Instantiate all Controllers, and this really will give you unexpected results and Headaches ;)
Also I should point at the viewResolver, as it will specify the path where the JSP for your viewResolving will be. Hope this helps you to start ;)

So long
Jan


Hi Jan,

I probably stumbled across what you mentioned above, regarding the invocation of multiple controllers at the same time, even if slightly different.
The issue I'm having is the following:

I have 3 portlets in one .war file, when I deploy the war I can see them as separate ones. What happens is, when I add all of them to a page they all display correctly, but as soon I invoke the action phase by submitting a form, does not matter on which portlet's, the page displays an error message for each portlet, saying "<portlet-name> is temporarily unavailable."

What I saw from my log is that all the portlets controller get invoked in some way, and I come up with three error saying that the .jsp file could not be found.
In particular, for the portlet on which I tried to submit the form, the error says that could not found the jsp that supposed to print the results after an action, and for the other two, their defaultRender.jsp.

What I think I understand is that, since all the portlets reside on the same page, when I submit something on that same page, their render phase is invoked, but then I can't see why that error.

Any idea regarding it would be much appreciated.

Please find my code in case you want to have a look at it. Link

Kind Regards,
Ettore.
Ettore Giallaurito, geändert vor 10 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

New Member Beiträge: 7 Beitrittsdatum: 11.06.13 Neueste Beiträge
Hi guys,

anyone out there had the chance to have a look at my post, I really don't have a clue about it.
Any help would be much apprecciated...

Thanks a lot in advance.
thumbnail
Jan Geißler, geändert vor 10 Jahren.

RE: Spring MVC Portlets (Annotation Approach) - Configuring Multiple Portl

Liferay Master Beiträge: 735 Beitrittsdatum: 05.07.11 Neueste Beiträge
Sorry for the late reply, but better late than never ;)

@ActionMapping(params = "action=actionOne")
^^

This is the Problem. You define ACTION but you dont pass the Action Name.
eg:


@ActionMapping(value = "DELETE_APPLICANTSTATUS", params = { "primaryId" })

and corresponding in the JSP:

<portlet:actionURL name="DELETE_APPLICANTSTATUS" var="DELETE_APPLICANTSTATUS_URL">
<portlet:param name="primaryId" value="${item.primaryId}" />
</portlet:actionURL>