Liferay 7.2 - MVCActionCommand Override
Liferay 7.2 - MVCActionCommand Override
Overview
This article describes how override Liferay's OOTB action commands.
Why do you need it?
You may need it to inject custom functionality before or after original MVCActionCommand execution: read additional data from request, save it to database, etc.
For developers familiar with Liferay 6.2 - this is a replacement for Struts Action hooks. Most of Struts Actions have been replaced with MVCCommands in the Liferay internal code - that's why extension point has been changed also.
MVCActionCommand implementation
1. Find MVCActionCommand, which you need to customize.
We'll customize user creation process. Thus, the target one will be:
com.liferay.users.admin.web.internal.portlet.action.EditUserMVCActionCommand
2. Check
mvc.command.name
and javax.portlet.name
properties.
For our class they are:
"javax.portlet.name=" + UsersAdminPortletKeys.MY_ORGANIZATIONS, "javax.portlet.name=" + UsersAdminPortletKeys.USERS_ADMIN, "mvc.command.name=/users_admin/edit_user"
, which is:
"javax.portlet.name=com_liferay_users_admin_web_portlet_MyOrganizationsPortlet", "javax.portlet.name=com_liferay_users_admin_web_portlet_UsersAdminPortlet", "mvc.command.name=/users_admin/edit_user"
if we skip the constants class.
3. Create a service module with custom MVCActionCommand (
CustomEditUserMVCActionCommand
here).- make it extend
com.liferay.portal.kernel.portlet.bridges.mvc.BaseMVCActionCommand
class and overridecom.lifedev.portlet.action.CustomEditUserMVCActionCommand.doProcessAction
method; - copy OSGi properties above to the created class;
- add
service.ranking
property to prioritize component over the original one:"service.ranking:Integer=100"
; - inject the original MVCActionCommand (specifying target component name):
@Reference(target = "(component.name=com.liferay.users.admin.web.internal.portlet.action.EditUserMVCActionCommand)") private MVCActionCommand mvcActionCommand;
- invoke original mvcActionCommand, and inject custom logic either before or after invocation.
Here is the result class sample:
import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.portlet.bridges.mvc.BaseMVCActionCommand; import com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; @Component( property = { "javax.portlet.name=com_liferay_users_admin_web_portlet_MyOrganizationsPortlet", "javax.portlet.name=com_liferay_users_admin_web_portlet_UsersAdminPortlet", "mvc.command.name=/users_admin/edit_user", "service.ranking:Integer=100" }, service = MVCActionCommand.class ) public class CustomEditUserMVCActionCommand extends BaseMVCActionCommand { @Override protected void doProcessAction(ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { _log.info("CustomEditUserMVCActionCommand, before original MVCActionCommand."); //todo: add pre- customization mvcActionCommand.processAction(actionRequest, actionResponse); _log.info("CustomEditUserMVCActionCommand, after original MVCActionCommand."); //todo: add post- customization } @Reference(target = "(component.name=com.liferay.users.admin.web.internal.portlet.action.EditUserMVCActionCommand)") private MVCActionCommand mvcActionCommand; private static Log _log = LogFactoryUtil.getLog(CustomEditUserMVCActionCommand.class); }
You can inject your business-logic instead of TODOs above.
Dependencies in
build.gradle
file:dependencies { compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel" compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations" compileOnly group: "javax.portlet", name: "portlet-api", version: "3.0.0" compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1" }
OSGi metadata in
bnd.bnd
, sample:Bundle-Name: LifeDev MVC Command Override Bundle-SymbolicName: com.lifedev.portlet.action Bundle-Version: 1.0.0
Deploy created module, and verify, that your custom MVCActionCommand is invoked together with the original one.
Enjoy 😏
Comments
Post a Comment