Creating Service Wrappers
With Service Wrappers, you can override default service methods to add extra functionality. For example, you may want the value of a field you’ve added to Liferay’s User
object to be saved whenever the Liferay API’s addUser
or updateUser
methods are called. Liferay’s service wrappers provide easy-to-use extension points for customizing Liferay’s services.
Deploying a Service Wrapper
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.120-ga120
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
Then, follow these steps to deploy the example:
-
Download and unzip the
liferay-j1c2.zip
example project.curl https://resources.learn.liferay.com/dxp/latest/en/liferay-development/liferay-internals/extending-liferay/liferay-j1c2.zip -O
unzip liferay-j1c2.zip
-
Build and deploy the project module.
cd liferay-j1c2
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
NoteThis command is the same as copying the deployed jars to
/opt/liferay/osgi/modules
on the Docker container. -
Confirm the deployment in the Liferay Docker container console.
STARTED com.acme.j1c2.impl_1.0.0 [1439]
-
To verify the example module’s customization, open your browser to
https://localhost:8080
. -
Log out of Liferay and log back in. The service wrapper prints this message to the Liferay Docker container console:
INFO [http-nio-8080-exec-6][J1C2UserLocalServiceWrapper:25] Invoking #authenticateByEmailAddress(long, String, String, Map, Map, Map)
This example prints a message to the console whenever the authenticateByEmailAddress
method is called.
Creating a Service Wrapper Class
- Choose the service you want to wrap. This example creates a service wrapper for
UserLocalService
, so it extendsUserLocalServiceWrapper
:
public class J1C2UserLocalServiceWrapper extends UserLocalServiceWrapper {
- Annotate the class so Liferay knows this is a service wrapper component.
@Component(service = ServiceWrapper.class)
- Choose the method you want to override and add your own implementation.
@Override
public int authenticateByEmailAddress(
long companyId, String emailAddress, String password,
Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
Map<String, Object> resultsMap)
throws PortalException {
if (_log.isInfoEnabled()) {
_log.info(
"Invoking #authenticateByEmailAddress(long, String, String, " +
"Map, Map, Map)");
}
return super.authenticateByEmailAddress(
companyId, emailAddress, password, headerMap, parameterMap,
resultsMap);
}
Overriding a Method
-
Open the
J1C2UserLocalServiceWrapper
class in your text editor or IDE. -
Inside the class, create a public method called
getUser
. This overridesUserLocalService
’sgetUser
method. As such, it must pass along
as an argument and return aUser
. This method should also throw aPortalException
. Make sure to add the@Override
annotation.@Override public User getUser(long userId) throws PortalException { }
-
Since this method returns the
User
object, import it at the top of the file.import com.liferay.portal.kernel.model.User;
-
Create a similar method to the one in the example so that every time the
getUser
method is called, it prints a message to the console.if (_log.isInfoEnabled()) { _log.info( "Invoking #getUser(long)"); }
-
You still want
getUser
to be called, so make the method return the results of callinggetUser
’s super method.return super.getUser(userId);
-
In the end, your method should look like this:
@Override public User getUser(long userId) throws PortalException { if (_log.isInfoEnabled()) { _log.info( "Invoking #getUser(long)"); } return super.getUser(userId); }
-
Build and deploy your module.
./gradlew build deploy -Ddeploy.docker.container.id=$(docker ps -lq)
Testing Your Service Wrapper
-
Go back to
https://localhost:8080
. -
Click My Profile in the User menu. This takes you to your profile page.
-
When you open your profile page, Liferay calls the
getUser
method a couple times. Check your console for the following message:
INFO [http-nio-8080-exec-4][J1C2UserLocalServiceWrapper:39] Invoking #getUser(long)
Congratulations! You’ve customized a service’s methods using a Liferay service wrapper.