Fórum

Action Classes with MVCPortlet

thumbnail
Marco Weiland, modificado 13 Anos atrás.

Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
hi,

is it possible to use multiple action classes with Liferay MVC Portlet?

i build a portlet from liferay ide, using mvcportlet and liferay 6.1 from trunk.
from that portlet template i see no way, to define multiple action paths.

its nice feature to bind actionmethod calls directly to name attribute of <actionURL>,
but that seems for me to get hundreds (maybe emoticon ) of "actionmethods" inside one
portletclass for bigger applications.

anybody any suggestions to call directly actionclasses inside one mvcportlet?

or maybe do i have wrong point of view?

cheers
marco
thumbnail
Lalit Jugran, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 33 Data de Entrada: 25/07/10 Postagens Recentes
Hi Marco Weiland ,

I don't have much idea about other mvc frameworks in java, but in struts there should be a single action class. By the way there is no use of making multiple action classes, rather you can make different util classes according to your requirement & call them directly from inside the single action class. Liferay MVCPortlet has made portlet development very easy in liferay..



emoticonemoticonemoticon
thumbnail
Marco Weiland, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
thank u for ur suggestions, i have done it with that ActionUtil classes...

i like mvportlet and i dont want to change or add other technoligies only for not having to much methods.

but in fact, u can map in struts multiple action paths to multiple action classes inside one portlet.
that is the feature i searched for in mvcportlet.

@ lalit : what do u mean as action class? i only have one blablaportletclass extending mvcportlet class, but no action class
which are called struts like from xml config like (liferay example) :

<action path="/document_library/select_file_entry" type="com.liferay.portlet.documentlibrary.action.ViewAction">
<forward name="portlet.document_library.error" path="portlet.document_library.error" />
<forward name="portlet.document_library.view" path="portlet.document_library.select_file_entry" />
</action>

<action path="/document_library/select_folder" type="com.liferay.portlet.documentlibrary.action.EditFolderAction">
<forward name="portlet.document_library.edit_folder" path="portlet.document_library.select_folder" />
<forward name="portlet.document_library.error" path="portlet.document_library.error" />
</action>

which are also called by one portlet ( or maybe they are reusable by other portlets, if u want to)
thumbnail
Deb Troxel, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 81 Data de Entrada: 22/02/10 Postagens Recentes
Hi Marco,

If I understand correctly what you are looking for, I think that it is possible to move the action methods into separate classes when using MVCPortlet.

I have not done this, but according to Rich Sezov's Liferay in Action book you can add this to your portlet.xml:
<init-param>
    <name>action.package.prefix</name>
    <value>com.myorg.myapp.portlet.action</value>
</init-param>

(Using your class package in the value, obviously)

The name of the action is used to locate the class in that package. If you have an action "MyAction" you should create <MyAction>ActionCommand which must must implement com.liferay.util.bridges.mvc.ActionCommand.

The processCommand() method of the <MyAction>ActionCommand class would be called to perform the action. Looking at the source of MVCPortlet, it appears that you can chain together a list of actions to perform in a single request. This would be done by setting the ActionRequest.ACTION_NAME parameter to a comma separated list of actions.

Like I said, I haven't used this yet, so please let us know if you try it and whether it works for you. emoticon
thumbnail
Marco Weiland, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
hi,
that sounds very good!! i will try that and give feedback!

thank u very much!
thumbnail
Marco Weiland, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
i got it working, for anybody else who want to use that here my guideline

1. u have to define the package ( or maybe comma separated list of packages) where to find ur implementations of
com.liferay.util.bridges.mvc.ActionCommand inside portlet.xml

		<init-param>
			<name>action.package.prefix</name>
			<value>de.goopen.erp.portlet.mvc</value>
		</init-param>


2. implement ur ActionCommand class

package de.goopen.erp.portlet.mvc;

import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;

import com.liferay.util.bridges.mvc.ActionCommand;

/**
 * @author mawe
 *
 */
public class ArticleActionCommand implements ActionCommand {

	/* (non-Javadoc)
	 * @see com.liferay.util.bridges.mvc.ActionCommand#processCommand(javax.portlet.PortletRequest, javax.portlet.PortletResponse)
	 */
	@Override
	public boolean processCommand(PortletRequest arg0, PortletResponse arg1) throws PortletException {
		System.out.println("this is the action command called from jsp form");
		return true;
	}

}


3. call it from ur jsp


<portlet:actionurl var="actionCommandUrl">
	<portlet:param name="<%=ActionRequest.ACTION_NAME %>" value="Article"></portlet:param>
</portlet:actionurl>
<aui:form action="" method="post" name="fmAc1">
	<aui:button name="actionCommandButton" value="actionCommand" onclick="<%= actionCommandUrl %>"></aui:button>
</aui:form>



be careful with naming convention ( u may debug commandcache initialisation to get it); the postfix "ActionCommand" will be attached to the value given in the portlet param.

@ deb: imho its not possible to chain multiple actioncommands inside one request, what u saw is that u can define multiple packages, where ur actioncommands r located @, thank u veryverymuch for ur hint!!!!!!!!!
thumbnail
Deb Troxel, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 81 Data de Entrada: 22/02/10 Postagens Recentes
Marco Weiland:

@ deb: imho its not possible to chain multiple actioncommands inside one request, what u saw is that u can define multiple packages, where ur actioncommands r located @, thank u veryverymuch for ur hint!!!!!!!!!


This made me curious 'cause it really looked like the code was there to handle an action list. What I found is that it does work, but there is a bug in how it parses the action list. If you don't add a comma at the end of the list, the last action won't be performed.

<portlet:actionurl var="actionCommandUrl">
   <portlet:param name="<%=ActionRequest.ACTION_NAME %>" value="First,Second" />
</portlet:actionurl>

Only triggers FirstActionCommand.

<portlet:actionurl var="actionCommandUrl">
   <portlet:param name="<%=ActionRequest.ACTION_NAME %>" value="First,Second," />
</portlet:actionurl>

Triggers both FirstActionCommand and SecondActionCommand.

I opened http://issues.liferay.com/browse/LPS-16422 to track this. The fix should be easy so I may make it one of my 100 Paper Cut fixes.
thumbnail
Marco Weiland, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
hi deb,

nice one, ur right! i only tried the method without ending comma, and did not debug further.

i fixed that problem in my env replacing the getActionCommandChain method with this:


public List<ActionCommand> getActionCommandChain(
String actionCommandChain) {

List<ActionCommand> actionCommands = _actionCommandChainCache.get(
actionCommandChain);

if (actionCommands != null) {
return actionCommands;
}else {
actionCommands = new ArrayList<ActionCommand>();
}

for ( String commandString : actionCommandChain.split(CharPool.COMMA+"\\s*")){

ActionCommand actionCommand = getActionCommand(commandString);

if (actionCommand != EMPTY) {
actionCommands.add(actionCommand);
}else {
if (_log.isWarnEnabled()) {
_log.warn(
"Unable to find ActionCommand " + actionCommandChain);
}
}
}

_actionCommandChainCache.put(actionCommandChain, actionCommands);

return actionCommands;
}


that is now working as expected, i was wondering about npe access on actionCommands.


<portlet:actionURL var="actionCommandUrl">
<portlet:param name="<%=ActionRequest.ACTION_NAME %>" value="Article,Supplier"></portlet:param>
</portlet:actionURL>


i also posted that into ur issue...

thanks
thumbnail
Deb Troxel, modificado 13 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 81 Data de Entrada: 22/02/10 Postagens Recentes
Nice! Thanks Marco. emoticon
thumbnail
Corentin R, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 92 Data de Entrada: 18/06/10 Postagens Recentes
Hello !
It seems not possible anymore to call action method from the MVCPortlet class when using the init-param
<init-param>
    <name>action.package.prefix</name>
    <value>com.myorg.myapp.portlet.action</value>
</init-param>

Then all <portlet:actionURL> in the portlet have to call separate ActionCommand class.

Am I wrong with that ?
thumbnail
Marco Weiland, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
i have attached u a portlet frame as war and as liferay ide project that is properly working in 6.1.x, if u did not patch actioncommandchain with http://issues.liferay.com/browse/LPS-16422, u have to attach comma after supplier inside actionurl to get it working
thumbnail
Marco Weiland, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
upd
thumbnail
chris Rowse, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

New Member Postagens: 20 Data de Entrada: 18/03/09 Postagens Recentes
Hi Marco / Deb

I have a bit of a conceptual block understanding the chain that Liferay MVC marries a liferay service builder definition to a form. I am reading Rich Sezof's Liferay in action and have copied his code for PRRegistration as far as I can.

What is the missing magic?

How do the names all tie up from Service Builder to Action class and view.jsp?

a) In serviceBuilder.xml I have
	<entity name="ISGSicCode" local-service="true" remote-service="true">
	</entity>


b) Then I have an action

package com.shorai.isg.action
public class Sic extends MVCPortlet {
	public void addSic(ActionRequest request, ActionResponse response) throws Exception {


c) In portlet.xml

	<portlet>
		<portlet-name>sic</portlet-name>
		<display-name>Sic</display-name>
		<portlet-class>com.shorai.isg.action.Sic</portlet-class>
		<init-param>
			<name>view-jsp</name>
			<value>/html/sic/view.jsp</value>
		</init-param>
		<init-param>
   			 <name>action.package.prefix</name>
    		        <value>com.shorai.isg.action</value>
	</init-param></portlet>

d) In jsp

&lt;%@ page import="com.shorai.isg.action.Sic" %&gt;
&lt;%@ page import="com.shorai.isg.action.SicUtil" %&gt;
......
<portlet:actionurl name="addSic" var="addSicURL">
	<aui:form action="<%= addSicURL.toString() %>" method="post">
</aui:form></portlet:actionurl>

Tomcat responds

Caused by: org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 80 in the jsp file: /html/sic/view.jsp
addSicURL cannot be resolved
77:
78:
79: <portlet:actionurl name="addSic" var="addSicURL">
80:     <aui:form action="<%= addSicURL.toString() %>" method="post">
81:             <aui:fieldset label="Add Sic Code">
82:                     <aui:input name="code" />
83:                     <aui:input name="parent" />
Stacktrace:
        at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)
        at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)
</aui:fieldset></aui:form></portlet:actionurl>


when I look in view.java I find the following, but dont have a way to enumerate _jspx_page_context.
I tried enumerating the application, page, session and request attributes but cant find the missing addSicURL


java.lang.String addSicURL = null;<br>
addSicURL = (java.lang.String) _jspx_page_context.findAttribute("addSicURL");


thanks in advance, I've pulled nearlty all my remaining hair out on this one.

Chris
thumbnail
Marco Weiland, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
hi,
at first i did not reproduce that, but please mention, that tags must be terminated.

<portlet:actionURL name="addSic" var="addSicURL"> --> <portlet:actionURL name="addSic" var="addSicURL" />

maybe that could produce the compile error with resolving ur addSicURL.

further i do not recommend u to initialize any variable with null values ( regarding to old scjp best practices), which does not effect ur problem ...

try to terminate the tag, if it is not working, plz post entire stacktrace
thumbnail
Marco Weiland, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
for now i did reproduce ur problem, i think its the tag termination problem.

furhter, if u want to put the actionurl in the action attribute of the form, u have to define the aui button as type="submit", please have a look at the attachment to see actioncommandchaing working; i updated ur way
thumbnail
chris Rowse, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

New Member Postagens: 20 Data de Entrada: 18/03/09 Postagens Recentes
Hi Marco,
Thanks for the quick reply.

Its probably not the tags - I have checked them thoroughly with both XML validators and manually. I should have warned that I posted only stubs of the code.

I am primarily interested in understanding how the names in the jsp, portlet.xml, Portlet.java and service.xml relate to one another and manage the URL dynamically. This, I believe is where my misunderstanding and problem lies.

I have downloaded the examples from 'Liferay in Action' and can compile and run those. The error is therefore in my code, and I will figure it out and repost to this thread for future reference.

Many thanks for your trouble.

Chris
thumbnail
Brian Scott Schupbach, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

Expert Postagens: 329 Data de Entrada: 23/10/08 Postagens Recentes
Is there a way to forward to a different .jsp file from the ActionCommand class ? I've setup multiple actions but I can't figure out how to forward to another .jsp file. Is this even possible to do from the PortletRequest object?

Thanks,

Brian
thumbnail
David Ross, modificado 12 Anos atrás.

RE: Action Classes with MVCPortlet

New Member Postagens: 19 Data de Entrada: 09/07/08 Postagens Recentes
Yes, I think this is what you want.



public void myAction(ActionRequest request, ActionResponse response) {
	response.setRenderParameter("jspPage", "/html/mypage.jsp");
}



Thanks,

Dave
thumbnail
Brian Scott Schupbach, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Expert Postagens: 329 Data de Entrada: 23/10/08 Postagens Recentes
Thanks!
thumbnail
Brian Scott Schupbach, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Expert Postagens: 329 Data de Entrada: 23/10/08 Postagens Recentes
Is it possible to forward to another action class while in a separate one?

Thanks,

Brian
thumbnail
Marco Weiland, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
you can do it with the actioncommandchain, i think.

<portlet:actionURL var="actionCommandUrl">
<portlet:param name="<%=ActionRequest.ACTION_NAME %>" value="Article, Order, Balance"></portlet:param>
</portlet:actionURL>


Where ArticleActionCommand, OrderActionCommand and BalanceActionCommand are different actionclasses inside the
actionpackage.
thumbnail
Brian Scott Schupbach, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Expert Postagens: 329 Data de Entrada: 23/10/08 Postagens Recentes
Thanks, Marco! That is good to know.

Brian
thumbnail
Tanaji M. Londhe, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Regular Member Postagens: 194 Data de Entrada: 25/04/12 Postagens Recentes
Hi All,
Is it possible to use my custom method name instead of using
public boolean processCommand(PortletRequest actionRequest, PortletResponse actionResponse)
throws PortletException {
-------------------------
}

e.g I want to separate this method into another action class from my portlet class.
public void myActionMtd(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
---------------------------
}
I have done this by using ActionCommand interface, but i want to use my custom name for that method instead of processCommand.
thumbnail
Marco Weiland, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Junior Member Postagens: 26 Data de Entrada: 28/10/07 Postagens Recentes
from my point of view, thats breaking the nice encapsulation and separation of concerns the actioncommand pattern follows. looking at the implementation of the actioncommand i dont find any way to do that; let me know, if you find something, but that possibility will cause some method overload like in portletclass imho.
thumbnail
Tanaji M. Londhe, modificado 11 Anos atrás.

RE: Action Classes with MVCPortlet

Regular Member Postagens: 194 Data de Entrada: 25/04/12 Postagens Recentes
Hi Macro,
Thanks for reply, sure I will update, if I get solution for this problem.