« 返回

Overriding and adding struts actions from hook plugins

Company Blogs 2011年1月17日 按 Mika Koivisto Staff

This is a new cool feature I worked on with Brian and it’s coming on 6.1 as well as 6.0 EE SP2 and 5.2 EE SP6. With this feature you can add new struts actions to portal from a hook plugin and you can override any existing action with it.

There are two interfaces com.liferay.portal.kernel.struts.StrutsAction and com.liferay.portal.kernel.struts.StrutsPortletAction. The StrutsAction is used for regular struts actions like /c/portal/update_password and StrutsPortletAction is used for those that are used from portlets.

Let’s create a new simple hook to test it out. This hook will create a new struts path /c/portal/sample and wraps an existing struts action. Start by creating a new hook plugin in your plugins SDK. I’ll call it sample-struts-action.

./create.sh sample-struts-action

Next edit the liferay-hook.xml and add following fragment:

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">

<hook>
	<portal-properties>portal.properties</portal-properties>
	<custom-jsp-dir>/META-INF/custom_jsps</custom-jsp-dir>
	<struts-action>
		<struts-action-path>/portal/sample</struts-action-path>
		<struts-action-impl>com.liferay.samplestrutsaction.hook.action.SampleStrutsAction</struts-action-impl>
	</struts-action>
	<struts-action>
		<struts-action-path>/message_boards/view</struts-action-path>
		<struts-action-impl>com.liferay.samplestrutsaction.hook.action.SampleStrutsPortletAction</struts-action-impl>
	</struts-action>
</hook>

Next we need to create the struts action like below:

package com.liferay.samplestrutsaction.hook.action;

import com.liferay.portal.kernel.struts.BaseStrutsAction;
import com.liferay.portal.kernel.util.ParamUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Mika Koivisto
 */
public class SampleStrutsAction extends BaseStrutsAction {

	public String execute(
		HttpServletRequest request, HttpServletResponse response)
		throws Exception {

		String name = ParamUtil.get(request, "name", "World");

		request.setAttribute("name", name);

		return "/portal/sample.jsp";
	}

}

Next create the second Struts action. This one will actually wrap ViewAction of message boards portlet.

package com.liferay.samplestrutsaction.hook.action;

import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.struts.StrutsPortletAction;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

/**
 * @author Mika Koivisto
 */
public class SampleStrutsPortletAction extends BaseStrutsPortletAction {

	public void processAction(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ActionRequest actionRequest,
			ActionResponse actionResponse)
		throws Exception {

		originalStrutsPortletAction.processAction(
			originalStrutsPortletAction, portletConfig, actionRequest,
			actionResponse);
	}

	public String render(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, RenderRequest renderRequest,
			RenderResponse renderResponse)
		throws Exception {

		System.out.println("Wrapped /message_boards/view action");

		return originalStrutsPortletAction.render(
			null, portletConfig, renderRequest, renderResponse);
	}

	public void serveResource(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ResourceRequest resourceRequest,
			ResourceResponse resourceResponse)
		throws Exception {

		originalStrutsPortletAction.serveResource(
			originalStrutsPortletAction, portletConfig, resourceRequest,
			resourceResponse);
	}

}

Then we need to create the JSP in docroot/META-INF/custom_jsps/html/portal/sample.jsp

Hello !

And lastly we need to create portal.properties in docroot/WEB-INF/src

auth.public.paths=/portal/sample

Now we are ready to deploy the plugin and see if it works. Just run ant deploy in your plugins sdk to deploy it.

You should see following in your tomcat console:

22:01:29,635 INFO  [AutoDeployDir:167] Processing sample-struts-action-hook-6.1.0.1.war
22:01:29,638 INFO  [HookAutoDeployListener:43] Copying web plugin for /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war
  Expanding: /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war into /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF/classes
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF/classes
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/META-INF
  Copying 12 files to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/webapps/sample-struts-action-hook
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/webapps/sample-struts-action-hook
  Deleting directory /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299
22:01:30,486 INFO  [HookAutoDeployListener:49] Hook for /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war copied successfully. Deployment will start in a few seconds.
Jan 17, 2011 10:01:39 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory sample-struts-action-hook
22:01:39,727 INFO  [PluginPackageUtil:1080] Reading plugin package for sample-struts-action-hook
22:01:39,759 INFO  [HookHotDeployListener:432] Registering hook for sample-struts-action-hook
22:01:39,770 INFO  [HookHotDeployListener:717] Hook for sample-struts-action-hook is available for use

Now try to access http://localhost:8080/c/portal/sample. It will ask you to sign in and once you sign in you should see the message Hello World! in your browser. You can add a paramer name to the url to change the message. If you access message boards it will print the message "Wrapped /message_boards/view action" in tomcat console and continue to render message boards as if nothing was changed.

Now our sample was really simple one. The return value from the execute method is the view where the request is dispatched next. This can be path to JSP, an existing struts forward or tiles definition. Returning null means that your action has handled the view already. Now you could try to return for instance portal.terms_of_use to display the terms of use.

You can download this sample plugin from svn://svn.liferay.com/repos/public/plugins/trunk/hooks/sample-struts-action-hook. The username is guest and password is empty.

UPDATE: We changed the API so that the original action is passed in so that you can also wrap it with your own logic instead of replacing. I also added a new hook property auth.public.paths so it allows you to set new public paths from hooks. I also added a StrutsPortletAction into to the sample and that demonstrates wrapping an existing action.

讨论主题回复 作者 日期
cooooooooooooooooooool feature! Thanks a lot,... Jonas Yuan 2011年1月17日 下午2:48
Awesome Mika! I'm glad you guys worked on this. Ray Augé 2011年1月17日 下午2:56
Really Nice Features.... Good Work Mika & Team Pravin Pawar 2011年1月17日 下午9:13
Excellent! James Min 2011年1月17日 下午9:38
Hienoa Mika, this is useful feature. Sampsa Sohlman 2011年1月17日 下午9:41
Nice Feature! Jay Patel 2011年1月17日 下午9:54
Sweet! Nice work Amos Fong 2011年1月17日 下午10:39
outstanding, give more power to the hooks. thx... Armin Cyrus Dahncke 2011年1月18日 上午1:04
Awesome!! Ruth Coca 2011年1月18日 上午4:52
Great feature!! Peter Mesotten 2011年1月18日 上午6:19
This is a fantastic feature, most awaited to... Ahamed Hasan 2011年1月18日 上午10:26
We just made it even more powerful by passing... Mika Koivisto 2011年1月18日 下午2:30
Cool feature! Can't wait to get my hands on it.. Rushikesh S Thakkar 2011年1月21日 下午3:15
Great Feature. Very useful one.. Yogesh Agrawal 2011年2月5日 上午5:19
Awesome - exactly what I went looking for....... James Korotney 2011年3月16日 下午2:14
Awesome feature. Is it possible to create... Sandeep Nair 2011年3月27日 下午10:41
Yes you can use custom services in the hook... Mika Koivisto 2011年3月28日 下午12:58
[...] Luis Rodríguez Fernández: Hi Sam, I am... 匿名 2011年5月14日 下午11:51
[...] Adding a hook to Liferay 05/06/2011 by... 匿名 2011年6月5日 下午2:39
About one year ago, I worked in a little... Aig Loss 2011年6月24日 上午8:57
With Liferay 6.06 I am not finding... Mike Oliver 2011年7月11日 下午7:39
Nice! Do you know if is possible to override an... Roberto Barchino 2011年7月13日 上午2:51
Mike and Roberto this is only available in... Mika Koivisto 2011年7月13日 上午11:32
Hi Roberto, I've posted the jar, and a sample... Aig Loss 2011年7月13日 下午1:32
Hi Aig, is there something like zeep-o-tron for... alex wom 2011年7月18日 上午12:56
I have'nt tested it yet for that Liferay... Aig Loss 2011年7月18日 上午4:10
Hi Alex, finally I've found some time to test... Aig Loss 2011年7月23日 上午11:27
[...] Liferay just released their second... 匿名 2011年8月2日 上午2:13
[...] If you are overriding just the jsp, you... 匿名 2011年9月9日 上午4:46
[...] Hello, all! We want to associate journal... 匿名 2011年9月9日 下午1:11
Realy cool. Canching the Portal will be so much... Jan Bub 2011年9月10日 上午2:51
I am trying to create a hook plugin by... Rajesh Chaurasia 2011年9月18日 上午7:30
Was a very nice feature and i tried and... Kamesh Sampath 2011年10月22日 上午8:35
[...] Following this blog, i was able use the... 匿名 2011年10月22日 上午8:45
Rajesh Chaurasia, are you sure you have the... Mika Koivisto 2011年10月24日 上午10:37
Kamesh Sampath, can you provide me a example of... Mika Koivisto 2011年10月24日 上午10:39
Isn't this supported by simply delegating those... Ray Augé 2011年10月24日 上午10:47
Ray that would only work if you are overriding... Mika Koivisto 2011年10月24日 上午10:53
[...] I totally agree with you Jeff. One thing... 匿名 2011年11月22日 下午12:24
I ve a similar problem of Rajesh Chaurasia i... Paolo Pilitti 2011年11月25日 上午6:33
[...] portal-properties (called portal... 匿名 2011年11月30日 上午11:24
[...] What do you want to happen when the user... 匿名 2011年12月1日 下午4:04
Great, informative article! Really useful... Kris Sokolovski 2011年12月2日 上午3:49
Great feature so far! ... but... I am trying... Jana Volkmer 2011年12月13日 上午12:09
I'm able to wrap the message_boards/view action... Rex Petersen 2011年12月31日 下午12:45
This is a nice feature indeeed, but there seems... Jon Haikarainen 2012年1月5日 上午6:39
I have also hit the same exact problem as Rex... Trevor Ackerman 2012年1月6日 下午1:31
Hey can you open a ticket for this and post the... Mika Koivisto 2012年1月6日 下午1:56
I'm assuming you are responding to Jon... Trevor Ackerman 2012年1月9日 下午1:53
Finally I got the ticket for the... Jon Haikarainen 2012年1月10日 上午3:35
Is this supported in 6.0.6 CE R V 2012年1月18日 下午12:37
R V this is implemented in 6.1.0 CE and... Mika Koivisto 2012年1月18日 下午12:46
When I override an existing JSP e.g. lets say... Kamesh Sampath 2012年2月7日 下午4:01
[...] Now here’s the relatively new way to... 匿名 2012年2月10日 上午8:18
[...] Buenos días. A ver si alguien me pude... 匿名 2012年2月13日 上午1:47
Is it posible to extend Action that are defined... Mark Stein 2012年2月21日 上午7:34
Mark, unfortunately no. You can only extend... Mika Koivisto 2012年2月21日 上午11:14
cool feature : ) Scott Lee 2012年2月27日 下午3:07
Hi all this is cool feature and i am trying to... Muradali Hasan 2012年3月28日 上午3:03
Hi, I got class cast exception when I access... Zhidao Xu 2012年4月18日 下午7:52
i want to create a hook for blog portlet and... iqbal ahmed 2012年4月19日 上午4:35
Hello Mika Koivisto and other Liferay experts, ... Elijah "Ellie" Mangason 2012年5月16日 上午8:40
[...] I have recently been working on a task to... 匿名 2012年5月17日 下午3:46
Hello! I read your article several times, and... Elijah "Ellie" Mangason 2012年5月21日 上午8:42
[...] Hi, even if your statement is true, I got... 匿名 2012年6月18日 上午9:41
[...] Hello, Version : Liferay EE 6.0 SP2... 匿名 2012年7月11日 上午2:03
Hi Yana, i would like to answer (maybe too... Sven Kwiotek 2012年8月22日 上午6:14
It is a bit challenging to add a new action... Muhammed Shakir 2012年10月7日 上午3:09
Hi Does tiles-defs-ext.xml file can be put... Tomasz Sokół 2013年2月4日 上午6:18
Tiles definitions through the hook is not... Mika Koivisto 2013年2月4日 上午9:16
Hi Mohamed, when I followed the link you gave,... Nabil Bahtat 2014年7月13日 上午6:44
Hi Muhammed, I am trying to implement a... Mashuk Choudhury 2014年7月18日 上午1:13
Awesome feature, using it 1st time Liferay... Nasir Hussain 2012年12月3日 上午3:50
nice feature it is. However I'm running into... stephan t 2012年12月13日 上午2:11
Trying to do the same thing (except just on add... Gary Pinkham 2013年4月4日 上午8:17
[...] shivam aggarwal: Hi Apoorva, I was trying... 匿名 2012年12月13日 上午9:18
[...] Hi Dave, Please refer this link. Hope... 匿名 2013年3月17日 下午11:59
Hi, I am extending "CreateAccountAction" class... Laxman Rana 2013年4月25日 上午6:58
Laxman, I am doing something similar, but you... Steven Linzer 2013年6月12日 上午7:25
FYI, you don't even need to have as struts... Ray Augé 2013年6月12日 上午7:35
Ray, On your comment: "you don't even need to... Steven Linzer 2013年6月13日 上午10:41
Hi How to add struts action in LR 6.0.5 Thanks Mohammad Azharuddin 2013年5月3日 上午3:54
Same as Zhidao Xu here! I'm getting a... Juanjo Hernández Cánovas 2013年10月3日 上午7:49
Hi Mika, I tried to override /polls/view by... Nabil Bahtat 2014年2月11日 下午1:58
Nabil, we don't currently support overriding... Mika Koivisto 2014年2月11日 下午2:16
Thanks Mika, is there any workaround ? Thanks,... Nabil Bahtat 2014年2月11日 下午9:44
I'm trying to override OpenIdAction using... pspyra pspyra 2014年3月12日 上午7:13
*correct link is... pspyra pspyra 2014年4月24日 上午3:08
How is possible to add custom fordwards into... Jonatan Oyola 2014年11月3日 上午10:45
[...] Hi All, I have created hook plugin and In... 匿名 2016年4月29日 下午5:21

cooooooooooooooooooool feature! Thanks a lot, Mika and Brian.
在 11-1-17 下午2:48 发帖。
Awesome Mika! I'm glad you guys worked on this.
在 11-1-17 下午2:56 发帖。
Really Nice Features....
Good Work Mika & Team
在 11-1-17 下午9:13 发帖以回复 Ray Augé
在 11-1-17 下午9:38 发帖。
Hienoa Mika, this is useful feature.
在 11-1-17 下午9:41 发帖。
在 11-1-17 下午9:54 发帖。
在 11-1-17 下午10:39 发帖。
outstanding,

give more power to the hooks. thx mika
在 11-1-18 上午1:04 发帖。
在 11-1-18 上午4:52 发帖。
在 11-1-18 上午6:19 发帖。
This is a fantastic feature, most awaited to get realized thru a hook plugin. Nice Job Mika and Brian. Thank you so much.
在 11-1-18 上午10:26 发帖。
We just made it even more powerful by passing in reference to the original action so that you can just wrap it if you so wish.
在 11-1-18 下午2:30 发帖。
Cool feature! Can't wait to get my hands on it..
在 11-1-21 下午3:15 发帖。
Great Feature.
Very useful one..
在 11-2-5 上午5:19 发帖。
Awesome - exactly what I went looking for.... when can I have it :-)
在 11-3-16 下午2:14 发帖。
Awesome feature. Is it possible to create custom services in hook and then call the new services from these overrided struts action? And any hint on when liferay 6.0 EE SP2 will be released so that i can use these in my project?
在 11-3-27 下午10:41 发帖以回复 James Korotney
Yes you can use custom services in the hook plugin from the action classes.
在 11-3-28 下午12:58 发帖以回复 Sandeep Nair
[...] Luis Rodríguez Fernández: Hi Sam, I am extending the /announcements/edit_entry action implementing a hook. I have created a hook project and in the src folder I have my implementation of the... [...] Read More
在 11-5-14 下午11:51 发帖。
[...] Adding a hook to Liferay 05/06/2011 by Steffen Luypaert Leave a Comment In this article, we elaborate on Liferay hooks, which are a type of plugin for the Java-based Liferay portal. We discuss what... [...] Read More
在 11-6-5 下午2:39 发帖。
About one year ago, I worked in a little development that allowed me to override/add, struts actions, tiles configurations, spring beans, and add classs to Liferay usng hooks...
You con find some clues in a 3-posts series at http://aigloss.blogspot.com/2011/04/liferay-portal-server-avoiding-use-of.html.
I­'ve been using it in productin environments since there and has been tested in LF5.1.2 (it was originally developed for that LF version), ang earlier versions of Liferay 6 CE.
在 11-6-24 上午8:57 发帖以回复
With Liferay 6.06 I am not finding com.liferay.portal.kernel.struts.BaseStrutsAction to import.
在 11-7-11 下午7:39 发帖。
Nice!
Do you know if is possible to override an struts action in a hook without using ext--enviroment in liferay 5.2.3? Because in the DTD hook of liferay 5.2.3 there are the <struts-action> tags... but know I see that this will be a new functionality of liferay 6.1.
I'm little bit confusing.

Can anyone help me?

Thank you.
在 11-7-13 上午2:51 发帖以回复 Mike Oliver
Mike and Roberto this is only available in upcoming 6.1 and 6.0 EE SP2 and 5.2 EE SP6. Neither 6.0 CE or 5.2 CE has this feature as it was developed after their release.
在 11-7-13 上午11:32 发帖以回复 Roberto Barchino
Hi Roberto,
I've posted the jar, and a sample hook for Liferay 5.2.3 with the module I was talking in the other post. As told, using that you'll be able to override/add struts configs and actions, tiles configs, spring beans, plus any other thing Liferay allow you to do using hook.
You can check that sample out at http://aigloss.blogspot.com/2011/07/liferay-portal-server-avoiding-use-of.html
Ho­pe you like it!
在 11-7-13 下午1:32 发帖以回复 Mika Koivisto
Hi Aig, is there something like zeep-o-tron for Liferay 6.0.6?
在 11-7-18 上午12:56 发帖以回复 Aig Loss
I have'nt tested it yet for that Liferay version, but, unless there is some package modification or something like that, it will surely work.
I'll try to test it and upload a working sample for LF 6.0.6 during this week. Just uploaded it for 5.2.3 first because of Roberto needs.
在 11-7-18 上午4:10 发帖以回复 alex wom
Hi Alex,
finally I've found some time to test it on LF 6.0.6 and make some modifications. You can find the details here: http://aigloss.blogspot.com/2011/07/zeep-otron-for-liferay-6.html.

Hope you like it!
在 11-7-23 上午11:27 发帖以回复 Aig Loss
[...] Liferay just released their second service pack for 6.0 enterprise customers. Apart from lost of small bug fixes, they included one welcome enhancement to the hooks system: overriding struts actions... [...] Read More
在 11-8-2 上午2:13 发帖。
[...] If you are overriding just the jsp, you could do that via hook. If you are overriding struts action ,you may have to use the ext-plugin until overriding them is available via plugins.... [...] Read More
在 11-9-9 上午4:46 发帖。
[...] Hello, all! We want to associate journal articles to polls in such a way that we can automatically provide a link to an article when showing a poll. For that, we intend to follow the following steps:... [...] Read More
在 11-9-9 下午1:11 发帖。
Realy cool. Canching the Portal will be so much easier.
在 11-9-10 上午2:51 发帖。
I am trying to create a hook plugin by extending the class EditPagesAction .I have provided my version of action class with name NPPEditPagesAction.I am able to deploy my plugin into liferay .But I am not able to excute my implemention class code given in NPPEditPagesAction.I tried to set breakpoint in my code but I am not able to get the Debug perspecetive in eclipse.
hook.xml:
--------------
<hook>
<custom-jsp-dir>/WEB-INF</custom-jsp-dir>
­<struts-action>
<struts-action-path>/layout_management/edit_pages</struts-acti­on-path>
<struts-action-impl>com.liferay.portlet.communities.action.NPPEditPag­esAction</struts-action-impl>
</struts-action>
</hook>


Implementiaon :

public class NPPEditPagesAction extends EditPagesAction {

public void processAction(ActionMapping mapping, ActionForm form,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {

System.out.println("Inside processAction...createTheme()");
String cmd = ParamUtil.getString(actionRequest, Constants.CMD);

try {
if (cmd.equals("createtheme")) {
createTheme(actionRequest);
}

super­.processAction(mapping, form, portletConfig, actionRequest,actionResponse);

} catch (Exception e) {

}
}

public ActionForward render(ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
RenderRequest renderRequest, RenderResponse renderResponse)
throws Exception {

return super.render(mapping, form, portletConfig, renderRequest, renderResponse);
//return mapping.findForward(getForward(renderRequest, "portlet.communities.edit_pages"));

}

@SuppressWarnings("static-access")
publ­ic static void createTheme(ActionRequest actionRequest) {

System.out.println("Inside createTheme...");
ThemeUtil themeUtil = new ThemeUtil();
final String themeZipFilePath = ThemeUtil.SAMPLE_THEMES_PATH;
final String themeConfigFilePath = ThemeUtil.THEMES_CONFIG_PATH;
try{
//To Modify liferay-look-and-feel.xml
themeUtil.getXMLDetails(themeConfigFilePath);
­
//To Extract the sample themes zip folder to tomcat location
themeUtil.extractFolder(themeZipFilePath);

} catch (Exception ex) {
ex.printStackTrace();
}

}

///edit_pages_look_and_feel.jsp
<liferay-ui:­section>
<div style="width: 40%;">theme name:</div>
<input type="text" id="name">
<div style="width: 40%;">theme id:</div>
<input type="text" id="id"><br>
<div style="width: 40%;">body background:</div>
<input type="text" id="background" class="color"><br>
<div style="width: 40%;">bgcolor:</div>
<input type="text" id="bgcolor" class="color"><br>
<input type="button" value="<liferay-ui:message key="save" />" onclick="<portlet:namespace />createTheme();" />
</liferay-ui:section>


edit_pages.jsp
---------------

function <portlet:namespace />createTheme() {
alert("Hi:Inside createtheme....");
document.<portlet:namespace />fm.<portlet:namespace /><%= Constants.CMD %>.value = "createtheme";
submitForm(document.<portlet:namespace />fm);
}
在 11-9-18 上午7:30 发帖。
Was a very nice feature and i tried and implemented it successfully. I have small requirement not sure that is doable or not, i need to redirect to an existing Struts Action in one of the conditions during the render of the BaseStrutsPortletAction case. e..g redirecting to path "login/login"
在 11-10-22 上午8:35 发帖。
[...] Following this blog, i was able use the Struts Action hook to add new functionality to my existing hook . Now after doing my hook logic, i want to do a redirection or forward to an existing struts... [...] Read More
在 11-10-22 上午8:45 发帖。
Rajesh Chaurasia, are you sure you have the right struts-path? Some of the paths are changed automatically by com.liferay.portal.struts.StrutsActionPortletURL so that the path matches the struts-path of the portlet. This can be quite confusing because the struts path in the jsp is different that what is actually rendered.
在 11-10-24 上午10:37 发帖以回复
Kamesh Sampath, can you provide me a example of how would you do that with plain Struts? It might be possible if it's not then it might be something to consider adding.
在 11-10-24 上午10:39 发帖以回复 Mika Koivisto
Isn't this supported by simply delegating those cases back to:

"originalAction" which is the value of the execute's method ActionMapping parameter?
在 11-10-24 上午10:47 发帖以回复 Mika Koivisto
Ray that would only work if you are overriding that particular action. If you want to redirect from one action to another it would work. Well you could use response.sendRedirect().
在 11-10-24 上午10:53 发帖以回复 Ray Augé
[...] I totally agree with you Jeff. One thing i want to know i was looking into LR 6.1 CE B4 I had a look into MD Messages related code. Actually controller in this case was EditMessageAction extends... [...] Read More
在 11-11-22 下午12:24 发帖。
I ve a similar problem of Rajesh Chaurasia

i want override ...action.GetCategoriesAction
so i write the liferay-hook.xml

<struts-action>
<struts-action-path>/asset/get_categories</str­uts-action-path>
<struts-action-impl>it.reply.open.wt.asset.action.GetCategori­esAction</struts-action-impl>
</struts-action>

but when in my code it invokes this action it uses :
url: themeDisplay.getPathMain() + '/asset/get_categories'

adding the pathMain ( that in my case is /c/ ) so it cant find the action class...
but if i dont add the pathMain it cant find url.



there is a solution for this?
在 11-11-25 上午6:33 发帖以回复
[...] portal-properties (called portal properties hooks), language-properties (called language properties hooks), custom-jsp-dir (called custom JSPs hooks), custom-jsp-global (applying custom JSPs hooks... [...] Read More
在 11-11-30 上午11:24 发帖。
[...] What do you want to happen when the user presses decline ? i think many scenarios could be solved with a simple jsp hook. If you really need to change the action then you need to override it in ext if... [...] Read More
在 11-12-1 下午4:04 发帖。
Great, informative article! Really useful feature!

But I was stuck in one silly mistake in my liferay-hook.xml. The ORDER of elements really MATTERS!
It should be as described in "liferay-hook_6_0_0.dtd" (don't pay attention to version).

My liferay-hook.xml was:
<hook>
<custom-jsp-dir>/WEB-INF/custom_jsps</custom-jsp-dir>
<portal-propert­ies>portal.properties</portal-properties>
</hook>

This needed to be:
<hook>
<portal-properties>portal.properties</portal-properties>
<custom-jsp-d­ir>/WEB-INF/custom_jsps</custom-jsp-dir>
</hook>

I had problems to deploy it, and have gotten such ERROR:
ERROR [HotDeployUtil:114] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for Search1-hook
com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for Search1-hook
at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployExcepti­on(BaseHotDeployListener.java:46)
at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployLi­stener.java:271)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._doFireDeployEvent(HotDeployU­til.java:111)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(HotDeployUti­l.java:188)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil­.java:40)
at com.liferay.portal.kernel.servlet.HookContextListener.contextInitialized(HookCon­textListener.java:36)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4205­)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4704)
at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1282)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1380)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:306)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.ja­va:142)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1385­)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1649)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1658)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(Containe­rBase.java:1638)
at java.lang.Thread.run(Thread.java:619)

I am glad it's resolved now, hope this will help others!
在 11-12-2 上午3:49 发帖。
Great feature so far! ... but...

I am trying to create a jsp-Hook for the portlet-configuration tabs. I already figured out, my struts action has to extend BaseStrutsPortletAction. But if I add my own Action there, I get the error

2011-12-12 16:04:00 ERROR [PortletRequestProcessor:377] Forward does not exist

Any help or hint would be great!

(see also: this forum post )
在 11-12-13 上午12:09 发帖。
I'm able to wrap the message_boards/view action as you describe here. But when I attempt to wrap /login/facebook_connect_oauth I get a runtime exception: com.liferay.portal.struts.PortletActionAdapter cannot be cast to com.liferay.portal.struts.ActionAdapter.

If I instead extend the class BaseStrutsAction as below, the facebook login functionality ceases to work properly. Is there something fundamentally different about the FacebookConnectAction class or am I doing something wrong?

public class FacebookMyConnectAction extends BaseStrutsAction {

@Override
public String execute(StrutsAction originalStrutsAction,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// TODO Auto-generated method stub
return super.execute(originalStrutsAction, request, response);
}
在 11-12-31 下午12:45 发帖以回复 Jana Volkmer
This is a nice feature indeeed, but there seems to be a bug when wrapping actions that are sending redirects. In my case I'm trying to wrap com.liferay.portal.action.LoginAction (/c/portal/login) with a custom action.

In liferay-hook.xml I have the following:

<hook>
<portal-properties>portal.properties</portal-properties>
<struts-action>
<struts-action-path>/portal/login</struts-action-path>
<struts-action-impl>PortalLoginAction</struts-action-impl>
</struts-action>
</hook>

Then, my PortalLoginAction -class has the following appearance:

public class PortalLoginAction extends BaseStrutsAction {

@Override
public String execute(StrutsAction originalStrutsAction, HttpServletRequest request, HttpServletResponse response)
throws Exception {
//custom code
return originalStrutsAction.execute(request, response);
}
}

Everything works well here until reaching the execution of the original action. The problem seems to be that LoginAction.execute() uses response.sendRedirect() and returns null. The execute() method in com.liferay.portal.struts.StrutsActionAdapter in turn expects the original action to return an ActionForward, thus resulting in a NullPointerException (line 48).

Does anyone know a workaround for this problem? I'm using Liferay 6 EE SP2 and I wouldn't like to make any custom fixes to the code.
在 12-1-5 上午6:39 发帖。
I have also hit the same exact problem as Rex Petersen has above. In my case I am trying to override the action for the UpdateReminderQueryAction. The blog post does not make it obvious why the wrapper example above is extending BaseStrutsPortletAction. It is doing so because the action class for message boards view extends PortletAction.

Rex, in the body of your execute method listed above replace the call to super.execute() with this instead:

return originalStrutsAction.execute(request, response);

Mika, if you could enhance your blog to mention this part of the process it would be greatly appreciated.
在 12-1-6 下午1:31 发帖以回复 Jon Haikarainen
Hey can you open a ticket for this and post the ticket number here. It should work with returning null as the forward.
在 12-1-6 下午1:56 发帖以回复 Trevor Ackerman
I'm assuming you are responding to Jon Haikarainen. right?
在 12-1-9 下午1:53 发帖以回复 Mika Koivisto
Finally I got the ticket for the NullPointerException -case created: LPS-24734.

Personally I don't however have a problem with this anymore as it turned out that customizing the action wasn't necessary in this case.
在 12-1-10 上午3:35 发帖以回复 Trevor Ackerman
Is this supported in 6.0.6 CE
在 12-1-18 下午12:37 发帖。
R V this is implemented in 6.1.0 CE and backported to 6.0 EE SP2 so not available in 6.0.6 CE.
在 12-1-18 下午12:46 发帖以回复 R V
When I override an existing JSP e.g. lets say blogs/search.jsp, I faced couple of problems

1. I am not able to use the existing struts path "/blogs/search" eventhough I override the same in my hook.xml, its picking my class only when I give a alternate search path like "/blogs/search1"

2. When i return the existing JSP page via the Struts Portlet Action render method I see the basic Portlet CSS styles are gone.

Any thoughts on what I am missing and ways to fix them ?
在 12-2-7 下午4:01 发帖以回复 Mika Koivisto
[...] Now here’s the relatively new way to inject our own logic for this struts action without resorting to the Ext mechanism. (The current documentation on how to do this may be found in this Liferay Blog... [...] Read More
在 12-2-10 上午8:18 发帖。
[...] Buenos días. A ver si alguien me pude echar una mano con mi problema. Estoy desarrollando un hook del Asset Publisher en el cual es necesario que añada un nuevo checkbox en la pagina de configuración... [...] Read More
在 12-2-13 上午1:47 发帖。
Is it posible to extend Action that are defined in liferay/.../liferay-portlet.xml, for examle:

<portlet>
<portlet-name>56</portlet-name>
<icon>/html/icons/journal_content.­png</icon>
<struts-path>journal_content</struts-path>
<configuration-action-­class>com.liferay.portlet.journalcontent.action.ConfigurationActionImpl</configu­ration-action-class>
...
在 12-2-21 上午7:34 发帖以回复
Mark, unfortunately no. You can only extend actions that are defined in struts-config.xml
在 12-2-21 上午11:14 发帖以回复 Mark Stein
在 12-2-27 下午3:07 发帖以回复 Mika Koivisto
Hi all
this is cool feature and i am trying to implement this but i have one question
the default liferay action classes extends PortletAction class which is in portal-impl has method like getForward(),setForward(),sendRedirect(),

now when i am override class i am replacing extends PortletAction with BaseStrutsPortletAction in that i am unable to get those methods for that what i need to change any one can give update
在 12-3-28 上午3:03 发帖以回复 Scott Lee
Hi,
I got class cast exception when I access URL : [localhost:8080/c/message_boards/view]

02:50:33,129 ERROR [StripFilter:59] java.lang.ClassCastException: com.liferay.portal.struts.PortletActionAdapter cannot be cast to com.liferay.porta
struts.ActionAdapter
java.lang.ClassCastException: com.liferay.portal.struts.PortletActionAdapter cannot be cast to com.liferay.portal.struts.ActionAdapter
at com.liferay.portal.struts.PortalRequestProcessor.processActionCreate(PortalReque­stProcessor.java:485)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:230)
at com.liferay.portal.struts.PortalRequestProcessor.process(PortalRequestProcessor.­java:174)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at com.liferay.portal.servlet.MainServlet.callParentService(MainServlet.java:533)
at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:510)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilt­erChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.­java:210)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:72)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.j­ava:304)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.servlet.filters.gzip.GZipFilter.processFilter(GZipFilter.java­:123)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilte­r.java:201)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter.processFilter(NtlmPos­tFilter.java:83)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.ja­va:80)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:121)
at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.processFilter(V­irtualHostFilter.java:208)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:48)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:184)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:92)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.jav­a:738)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:203)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:105)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:164)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:92)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:164)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:92)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:184)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:92)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(Invoker­Filter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilt­erChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.­java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:2­24)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:1­69)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.jav­a:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118­)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor­.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractPro­tocol.java:539)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)­
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:8­86)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
在 12-4-18 下午7:52 发帖。
i want to create a hook for blog portlet and add image uploading and displaying those images in thumnails how should i proceed
在 12-4-19 上午4:35 发帖。
Hello Mika Koivisto and other Liferay experts,

I need to validate users on login with information they will enter into custom fields compared with that which is already in the database. After validation, I want to proceed to the login process by issuing them a temporary password. Can this be done in a hook-struts override using CreateAccountAction? Any help, tips, advice you have would be most appreciated. Thanks in advance!
在 12-5-16 上午8:40 发帖以回复 iqbal ahmed
[...] I have recently been working on a task to customize some of the aspects of Liferay's built in Login portlet. This article describes how to take advantage of the simple configuration items provided by... [...] Read More
在 12-5-17 下午3:46 发帖。
Hello!
I read your article several times, and found it to be very useful. I have implemented many of the features you outlined so clearly in your post. THANKS! The situation now is that we have a database of users that have some fields pre-populated: first name, last name, gender, and birthdate. On first time login, I need them to complete their registration, then login. I'm wondering which fields will trigger the Associate Account button, which allows a user to complete the login process. Any ideas?
在 12-5-21 上午8:42 发帖以回复
[...] Hi, even if your statement is true, I got the error : Only a type can be imported. x.y.service.XServiceUtil resolves to a package When accessing to my service in my override jsp. As Maxim Kovalev, I... [...] Read More
在 12-6-18 上午9:41 发帖。
[...] Hello, Version : Liferay EE 6.0 SP2 Business case: Override the terms of use according to the login user role I am trying to override the UpdateTermsOfUseAction class using liferay hook as per the... [...] Read More
在 12-7-11 上午2:03 发帖。
Hi Yana,
i would like to answer (maybe too late...)
try use in your overridden render method:
return originalStrutsPortletAction.render(originalStrutsPortletAction, portletConfig, renderRequest, renderResponse);
在 12-8-22 上午6:14 发帖以回复
It is a bit challenging to add a new action with a custom jsp and ensuring that the jsp is wrapped into the theme properly. I have got the solution and it works like a charm. You can find the solution here : http://www.liferayaddict.com/home/-/blogs/new-action-in-hook-in-liferay-6-1
在 12-10-7 上午3:09 发帖以回复 Sven Kwiotek
Awesome feature, using it 1st time Liferay rocks emoticon
在 12-12-3 上午3:50 发帖。
nice feature it is. However I'm running into problems with my example:
I would like to override only one method (the processAction method) of the EditUserAction (enterprise-admin). I ended up with the following:
public class MyEditUserAction extends BaseStrutsPortletAction {

@Override
public void processAction(StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {

String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
...

now the obvious problem: How do I access the protected methods implemented in the original EditUserAction, like sendRedirect() or addUser()?
Normally I would have extended EditUserAction overriding just one method. But with the Action sitting in portal-impl I can't and have to use the BaseStrutsPortletAction. So it seems I have to repeat the complete implementation of EditUserAction in MyEditUserAction, which I consider not good practice and not upgrade-safe.
What we'd need is a wrapper mechanism as it exists for services.
Any ideas on this?

Thanks.
在 12-12-13 上午2:11 发帖。
[...] shivam aggarwal: Hi Apoorva, I was trying to implement the solution you provided.Regarding the CustomLayoutAction class,I used a hook for it. But on deployment,following exception is thrown Caused by:... [...] Read More
在 12-12-13 上午9:18 发帖。
Hi
Does tiles-defs-ext.xml file can be put inside a hook or do I need to use ext plugin? I am looking a way to add a custom tiles definitions without using EXT. Is this possible?
在 13-2-4 上午6:18 发帖以回复 Muhammed Shakir AK Misarwala
Tiles definitions through the hook is not currently supported.
在 13-2-4 上午9:16 发帖以回复 Tomasz Sokół
[...] Hi Dave, Please refer this link. Hope that helps Thanks Rahul Sign in to vote. Flag Please sign in to flag this as inappropriate. Mark as an Answer [...] Read More
在 13-3-17 下午11:59 发帖。
Trying to do the same thing (except just on add user).. Have you come to a better conclusion than rewriting the entire action class? I guess there's falling back to Ext-plugin which I was just about to do when I noticed this post about using hooks instead.. (already have a hook so would be better to just add something to it vs creating a whole new ext-plugin)
在 13-4-4 上午8:17 发帖以回复 stephan t
Hi,
I am extending "CreateAccountAction" class in custom-hook for overriding action mapping in 'struts-config.xml' b'coz i wanted to override default create-account mechanism to include extra fields for user but while deploying hook i'm getting following error.

Caused by: java.lang.NoClassDefFoundError: com/liferay/portlet/login/action/CreateAccountAction

can you help me to resolve this.
在 13-4-25 上午6:58 发帖。
Hi
How to add struts action in LR 6.0.5
Thanks
在 13-5-3 上午3:54 发帖。
Laxman,

I am doing something similar, but you can not override PortletAction. You can override the action mapping so that your class will be executed before the CreateAccountAction or EditUserAction class is executed. This will help because you can run validation on the user input; if the input is good, your class will re-route the execution to CreateAccountAction. Else, you can throw an error to the screen.
Secondly, are your "extra fields" custom fields? If so, the New User screen does not show the custom fields tab. Only the update user does.

Steve
在 13-6-12 上午7:25 发帖以回复 Laxman Rana
FYI, you don't even need to have as struts action mapping/wrapper in order to "get" the values of custom fields included in any UI, whether those fields are actually liferay's "custom fields" OR just some arbitrary input fields that were glued into place. The ServiceContext object has a Map called "attributes" (Map<String,Serializable>) which contains all the request parameters by name.

So, suppose you have a "ServiceWrapper" (including methods which don't actually have a "ServiceContext" parameter). You can get the request parameters there.

Where the ServiceContext is a parameter, then you simply need to get the parameter by calling:

serviceContext.getAttribute("name")

OR for safety:

ParamUtil.getString(serviceContext, "name", "default");

If you happen to be in a method which does NOT have a ServiceContext parameter, do not fret. There is a thread local specially for that:

ServiceContextThreadLocal.getServiceContext()

HTH
在 13-6-12 上午7:35 发帖以回复 Steven Linzer
Ray,

On your comment: "you don't even need to have as struts action mapping/wrapper in order to "get" the values of custom fields", I agree fully. I was just saying that in order to "add to" the create/edit user functionality such as adding some server-side validation, you would need to override that action in the struts-config (in a hook) and insert your own StructsPortletAction.

Regards,
Steve
在 13-6-13 上午10:41 发帖以回复 Ray Augé
Same as Zhidao Xu here! I'm getting a ClassCastException:
com.liferay.portal.struts.ActionAdapter cannot be cast to com.liferay.portal.struts.PortletActionAdapter
I have made a message entry for this issue: https://www.liferay.com/es/community/forums/-/message_boards/message/30102664
在 13-10-3 上午7:49 发帖。
Hi Mika,
I tried to override /polls/view by extending BaseStrutsPortletAction,
I referenced my struts action classe in my file liferay-hook.xml.
The probleme is whenI deploy my hook, my classe action iss never called.
I Wonder if it's not because in struts-config.xml action /polls/view is not referencin a classe action but a jsp (<action path="/polls/view" forward="portlet.polls.view"/>).
Please can you help me to overcome this issue.
Many thanks.
Nabil
在 14-2-11 下午1:58 发帖。
Nabil, we don't currently support overriding forwards. There's a feature request for that. https://issues.liferay.com/browse/LPS-44115
在 14-2-11 下午2:16 发帖以回复 Nabil Bahtat
Thanks Mika,
is there any workaround ?
Thanks,
Nabil
在 14-2-11 下午9:44 发帖以回复 Mika Koivisto
I'm trying to override OpenIdAction using feature described in this article, but I am getting NoClassDefFoundError exceptions. I described my problem here
https://www.liferay.com/community/forums/-/message_boards/view_message/35589­747#_19_message_35589747
Is it possible to override OpenIdAction with the method you described?
在 14-3-12 上午7:13 发帖。
*correct link is
https://www.liferay.com/community/forums/-/message_boards/message/35589747
在 14-4-24 上午3:08 发帖以回复 pspyra pspyra
Hi Mohamed,
when I followed the link you gave, I could not find your source code.
Please I need your help.
Thanks,
Nabil
在 14-7-13 上午6:44 发帖以回复 Muhammed Shakir AK Misarwala
Hi Muhammed,
I am trying to implement a similar thing where I have a custom jsp and trying to load a theme up for the custom jsp. I tried accessing the link that you provided, but it does not work. If you have another link or could provide some pointers, I would be very grateful.

Thanks
Mashuk
在 14-7-18 上午1:13 发帖以回复 Muhammed Shakir AK Misarwala
How is possible to add custom fordwards into structs-config and tiles???
Tahnks
在 14-11-3 上午10:45 发帖。
[...] Hi All, I have created hook plugin and In that I'm trying to override below mentioned struct's actions, 1. /search/search and 2./search/view but I'm getting some Null Pointer exceptions. I have... [...] Read More
在 16-4-29 下午5:21 发帖。