Web Services in Liferay


What is web service

Web service is nothing but exposes your software as service for other application over the network. Applications can be written in any programming language and if they support the statandard they can be integrated.It removes the concern of writing custom interfaces and REST/HTTP Post based calls for each integration point.

How they can be used , examples

As of now we have not used this feature in our platform. but there are several ways this can be used.

1. Data Migration.

2. External third party software integration – Applications like Salesforge

Exposing an entity as a SOAP Webservice in Liferay

In this example we will create a table in Database and expose a method to update this table via web service

Create a table

CREATE TABLE [dbo].[MyBook](
  [bookid] [bigint] NOT NULL,
  [bookname] [varchar](500) NULL,
CONSTRAINT [PK_MyBook] PRIMARY KEY CLUSTERED
(
   [bookid] ASC
)

Generate Service Layer code for table

1) Create service.xml place it in ext-impl\src\com\ext\portlet\mybook\service.xml

<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_5_2_0.dtd">

<service-builder package-path="com.ext.portlet.mybook">
 <namespace>MyBook</namespace>
 <entity name="MyBook" local-service="true" remote-service="true">
  <column name="bookid" type="long" primary="true" />
  <column name="bookname" type="String" />
 </entity>
 <exceptions>
  <exception>BookEntryName</exception>
 </exceptions>
</service-builder>
2) Go to ext-impl\build-parent.xml and add ant task to build this service.
<target name="build-service-portlet-mybook">
  <antcall target="build-service">
     <param name="service.file" value="src/com/ext/portlet/mybook/service.xml" />
  </antcall>
</target>
run the newly created ant task ‘build-service-portlet-mybook’. It will generate service layer code for you.

Now we will write a method to which will add a new book entry to the table.Open the generated file MyBookServiceImpl.java. if your entity name is ‘MyEntity’ in service.xml the generated class name will MyEntityServiceImpl.java

public MyBook addBook(String bookName) throws PortalException, SystemException {
  MyBook  mybook = null;
  long bookId = CounterLocalServiceUtil.increment(MyBook.class.getName());
  mybook = MyBookUtil.create(bookId);
  mybook.setBookname(bookName);
  return MyBookUtil.update(mybook, false);
}

Once this is done run the newly created ant task ‘build-service-portlet-mybook’ again. It will propogate this method rest of the interfaces and classes.Generate web service code for this method

Go to ext-impl\build-parent.xml and add a new ant task to generate the web service.

<target name="build-wssd-portlet-mybook">
  <antcall target="build-wsdd">
    <param name="service.file" value="src/com/ext/portlet/mybook/service.xml" />
  </antcall>
</target>

run the newly created ant task ‘build-wssd-portlet-mybook’. It will generate web service layer code for you.

Later on for easier convenience , you can add following task in ext-impl\build-parent.xml to build service and wsdd at same time.

<target name="build-mybook-service-wssd">
   <antcall target="build-service-portlet-mybook" />
   <antcall target="build-wssd-portlet-mybook" />
</target>

Consuming  Liferay Web services

  • Enabling web services

The portal uses Apache Axis to generate web services. The default Axis configuration is specified in the server-config.wsdd file under the /portal/tunnel-web/ docroot/WEB-INF folder. type http://127.0.0.1:8080/ tunnel-web/axis in your browser, you will see a list of SOAP services.

To access a service remotely, the host must be allowed via the portal-ext. properties properties file. After that, the user must have permission to access the portal resources. The default settings to access a service remotely are specified in the portal.properties file as follows:

axis.servlet.hosts.allowed=127.0.0.1,SERVER_IP
axis.servlet.https.required=false

The code above shows the IPs to access the Axis servlet. You can input a blank list to allow any IP to access this servlet. SERVER_IP will be replaced with the IP of the host server. By default, 127.0.0.1 is the IP for local host. This is the reason that you can access web services only by the IP 127.0.0.1

  • Example to access services
  1. Service can be browsed at http://127.0.0.1:8080/tunnel-web/axis
  2. To access the wsdl , click on the wsdl for any of the service.This is the example for User Service wsdl http://127.0.0.1:8080/tunnel-web/axis/Portal_UserService?wsdl
  3. From WSDL you can generate stub and other classes using eclipse or netbeans.
  4. Following is the sample client code to call a  user service service
public class LiferayUserServiceClient {
    public static void main(String[] args) {
         try {
             UserServiceSoapServiceLocator locatorUser = new UserServiceSoapServiceLocator();
             UserServiceSoap soapUser = locatorUser.getPortal_UserService("http://abc:abc@127.0.0.1:8080/tunnel-web/secure/axis/Portal_UserService");
             UserSoap soapUserModel =  soapUser.getUserById(10806);
             System.out.println(" getEmailAddress:" + soapUserModel.getEmailAddress());
        } catch (Exception e) {
           e.printStackTrace();
        }
    }
}

38 thoughts on “Web Services in Liferay

  1. Hi Arvind,

    It was really great to learn from your article.

    I too am stucked with one issue wherein I want to access all the friends of a user alongwith their image data. All this needs to exposed as a web service.Since the user object does not include any image info, I planned to create a new model which includes picking the user first name. last name, user id and image data.
    Tried creating a similar seriveSeriailzer classes also and included implementation of my methid in the WallEntryServiceImpl file. However after building the service and wsdd, I could no where see the method getting exposed.

    May be I am not using the right approach for my case where I do not want to create a new entity altogether but use the existing columns present in two of the liferay tables and then expose the service. Do I need to make some entry in service.xml for this case too? If yes. what they should be ?

    Please suggest ASAP.

    Thanks.

    Can also check one of the posts of mine :
    http://www.liferay.com/community/forums/-/message_boards/message/4984907

    • What do you mean by image data , is it profile image?
      Profile Image or Portrait is saved in Image Table as bytes.
      The portraitID in User_ table is mapped to imageId in Image Table , thats how you can the image for each user. You dont need to write any new code to fetch the data.

      Thanks
      Arvind

  2. HI Team,
    Right now i am trying to read data from message board of life ray using web service and incorporate that in .Net.would you please tell me the name of Webservice and how i can implement it in my code.

    Thank You
    Regards
    Vishal Marne

  3. Hi,

    How can I create a user with address and phone via

    soapUser.addUser(…, List addresses, List phones, …)

    I mean how to construct addresses List?

    Thank you!

  4. Pingback: RE: Cómo generar Web Services a partir de servicios del Service Builder Lif - Foros - Liferay.com

  5. Hi Arvind,

    I tried using the above class LiferayUserServiceClient to call the service.
    I am getting a error :-
    AxisFault
    faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
    faultSubcode:
    faultString: java.rmi.RemoteException: PermissionChecker not initialized

    How do I resolve this?

    Using Soap UI, I modify my endpoint like http://{server}:8080/tunnel-web/secure/axis/Portal_UserService and pass the username/password…and it works.

    but programmatically how do I do it…..how to resolve PermissionChecker not initialized error? I am using 6.0.5

    • Hi Rajeev

      I just tested the WebService client in Liferay 6 and i am able to get the user. My Portal is setup to login using screen name. here is working client code, It little bit different from the Blog Post.

      import java.net.URL;
      import com.liferay.portal.model.UserSoap;
      import com.liferay.portal.service.http.UserServiceSoap;
      import com.liferay.portal.service.http.UserServiceSoapServiceLocator;

      public class LiferayUserServiceClient {
      public static void main(String[] args) {
      try {
      UserServiceSoapServiceLocator locatorUser = new UserServiceSoapServiceLocator();
      URL url = new URL(“http://arvind.mishra:youngsoft@127.0.0.1:8080/tunnel-web/secure/axis/Portal_UserService”);
      UserServiceSoap soapUser = locatorUser.getPortal_UserService(url);
      UserSoap soapUserModel = soapUser.getUserById(16369);
      System.out.println(” getEmailAddress:” + soapUserModel.getEmailAddress());
      } catch (Exception e) {
      e.printStackTrace();
      }
      }
      }

  6. Pingback: Web Services In Liferay - Blogs - Youngsoft

  7. Pingback: RE: WebService in liferay6 - Forums - Liferay.com

  8. Hi Arvind,

    Can u please tell me what is the means of abc in this url “http://abc:abc@127.0.0.1:8080/tunnel-web/secure/axis/Portal_UserService”.

    Thanks

  9. Hi Arvind,

    I am trying to add a user in liferay by using this code

    Portal_UserServiceSoapBindingStub stub = (Portal_UserServiceSoapBindingStub)locator.getPortal_UserService(new URL(“http://10130:test@192.168.2.189:18080/tunnel-web/secure/axis/Portal_UserService”);

    stub.addUser(
    companyId, //companyId,
    false, //autoPassword,
    firstName, //password1,
    firstName, //password2,
    false, //autoScreenName,
    screenName, //screenName,
    usersModel.getStrEmailAddress(), //emailAddress,
    usersModel.getStrLocale()+””, //locale,
    firstName, //firstName,
    ” “, //middleName,
    lastName, //lastName,
    0, //prefixId,
    0, //suffixId,
    true, //male,
    1, //birthdayMonth,
    1, //birthdayDay,
    1970, //birthdayYear,
    “default”, //jobTitle,
    organizationIds, //organizationIds,
    false //sendEmail
    );

    }

    Bt i m getting this error.

    [ConfigurationException] Exception:
    org.apache.axis.ConfigurationException: No service named Portal_UserService is available
    org.apache.axis.ConfigurationException: No service named Portal_UserService is available
    at org.apache.axis.configuration.FileProvider.getService(FileProvider.java:233)
    at org.apache.axis.AxisEngine.getService(AxisEngine.java:311)
    at org.apache.axis.MessageContext.setTargetService(MessageContext.java:755)
    at org.apache.axis.client.Call.invoke(Call.java:2671)
    at org.apache.axis.client.Call.invoke(Call.java:2424)
    at org.apache.axis.client.Call.invoke(Call.java:2347)
    at org.apache.axis.client.Call.invoke(Call.java:1804)
    at com.liferay.client.portal.service.http.Portal_UserServiceSoapBindingStub.addUser(Portal_UserServiceSoapBindingStub.java:807)
    at com.zycus.admin.controlleragent.TmsUserAgent.handleRenderRequest(TmsUserAgent.java:123)

    can u pls get me out from this problem .

    Thanks in advance.

  10. Hi Arvind,

    I am using Liferay Portal Community Edition 6.1.0 CE. While consuming web service I get the following exception.

    java.rmi.RemoteException: Runtime exception; nested exception is:
    deserialization error: deserialization error: java.lang.NumberFormatException: For input string: “”
    at com.sun.xml.rpc.client.StreamingSender._handleRuntimeExceptionInSend(StreamingSender.java:331)
    at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:313)

    My Code :

    try {
    Stub stub = (Stub) (new CustomerServiceSoapService_Impl().getPlugin_customer_CustomerService());
    stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
    “http://localhost:8080/Customer-portlet/api/axis/Plugin_customer_CustomerService?wsdl”);

    CustomerServiceSoap_Stub customerServiceSoapService = (CustomerServiceSoap_Stub) stub;

    CustomerSoap custList[] = customerServiceSoapService.getListByScreenName(“shakeelstha”);

    System.out.println(“Customer List Size :: ” + custList.length);

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

  11. Pingback: RE: Portlet with Web Service, store data in DB - Forums - Liferay.com

  12. Pingback: RE: Creating portlet using Liferay with Webservices - Forums - Liferay.com

    • Hello Arvind,

      Thank you for this nice article.

      I am using web services in my project.

      I am adding message board thread/post in to liferay through struts java application.

      Below is the URL for web service call.

      URL(“http://test:test@localhost:8080/tunnel-web/secure/axis/Portlet_MB_MBMessageService?wsdl”);

      Threads/posts added successfully, but The username and password i have set, is the admin.

      I want to add posted by username as logged in user. not as admin(test in above URL)

      I don’t have access to all username and password.

      How can i achieve that. Please suggest.

      Thanks.

  13. Hello All,
    I am doing a POC and below is my requirement.

    1. As user and roles detail are already part of many current existing different system, when ever Liferay uses the Uses details, it should not ready from its database. It should get the details from Cache or by invoking the esb service. Please suggest me, is this possible in Liferay ? I am using Liferay 6.1. Can Liferay provide a way to extend the functionality to user the users and roles details from other system ?

Leave a reply to Ankita Modi Cancel reply