Liferay Service Wrappers

Liferay Service Wrappers

How to override Liferay Services


Overview


Sometimes you may need to customize logic for a particular Liferay service. For some cases, when certain additional operations need to be performed on an entity itself, the Model Listener approach can be used. In other situations, when the service business-logic needs to be changed - Service Wrapper is a proper solution.


What is a Service Wrapper?


Service Wrapper is an extension point provided by Liferay to inject custom logic for Liferay services. As it’s clear from the name - Service Wrappers “wrap” Liferay Services and provide additional functionality on top of them. 

There is a ServiceWrapper interface with methods to set and get the wrapped service. Service Builder generates basic service wrapper implementations for each entity (both for local and remote services). For example, for User there are UserServiceWrapper and UserLocalServiceWrapper. These classes contain the default implementations for all service methods (using service calls delegation to the wrapped service) and can be used as base classes for a custom Service Wrapper.

An example of a Service Wrapper in Liferay sources is a MBMessageUserLocalServiceWrapper class in message-boards module, which updates user name in Message Boards, when user is updated.


How to implement a custom Service Wrapper?


To implement a custom Service Wrapper we need to create a module in the Liferay Workspace:



and implement a class which extends a base service wrapper. 

In this example we created a LifeDevUserServiceWrapper class, which extends UserLocalServiceWrapper and is marked as an OSGi component for ServiceWrapper service.
    

@Component(service = ServiceWrapper.class)

public class LifeDevUserServiceWrapper extends UserLocalServiceWrapper {



}


In the service wrapper class we may override any service methods, and extend the functionality in one of the following ways:

  • inject custom logic before the original service call;

  • inject custom logic after the original service call;

  • override original service completely.

In the example below a custom logging message is printed in updateUser method after invoking the original one:


@Override

public User updateUser(

       long userId, String oldPassword, String newPassword1,

       String newPassword2, boolean passwordReset,

       String reminderQueryQuestion, String reminderQueryAnswer,

       String screenName, String emailAddress, boolean portrait,

       byte[] portraitBytes, String languageId, String timeZoneId,

       String greeting, String comments, String firstName,

       String middleName, String lastName, long prefixListTypeId,

       long suffixListTypeId, boolean male, int birthdayMonth,

       int birthdayDay, int birthdayYear, String smsSn, String facebookSn,

       String jabberSn, String skypeSn, String twitterSn, String jobTitle,

       long[] groupIds, long[] organizationIds, long[] roleIds,

       List<UserGroupRole> userGroupRoles, long[] userGroupIds,

       ServiceContext serviceContext)

       throws PortalException {


   User user = super.updateUser(

           userId, oldPassword, newPassword1, newPassword2, passwordReset,

           reminderQueryQuestion, reminderQueryAnswer, screenName,

           emailAddress, portrait, portraitBytes, languageId, timeZoneId,

           greeting, comments, firstName, middleName, lastName,

           prefixListTypeId, suffixListTypeId, male, birthdayMonth,

           birthdayDay, birthdayYear, smsSn, facebookSn, jabberSn, skypeSn,

           twitterSn, jobTitle, groupIds, organizationIds, roleIds,

           userGroupRoles, userGroupIds, serviceContext);


   _log.info(String.format("User #%d '%s' has been updated.", user.getUserId(), user.getFullName()));


   return user;

}


After the module is deployed, an updateUser method from the custom service wrapper class will be invoked when the Liferay user is updated. It will call the original (wrapped) service first, and then print a custom logging message.


Enjoy 😏



Comments

Popular posts from this blog

Liferay Search Container Example

Liferay DXP - max upload file size

Liferay Keycloak integration