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
- Service can be browsed at http://127.0.0.1:8080/tunnel-web/axis
- 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
- From WSDL you can generate stub and other classes using eclipse or netbeans.
- 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(); } } }
Great content Mishra,,,, U alwys rock……
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
You have done it again! Superb article.
Hi Arvind, your articel is great but how to call addBook web service that you created before?
The example in post is for user service. You can replace it with bookservice.
so, where can I get MyBookServiceSoapServiceLocator and MyBookServiceSoap ? I can not find any of these files. Thanks for replying.
Never mind about my question before. I have already solved the problem. Thank you for post. It is really helpfull.
Hi Franc, Service Builder is not generating MyBookServiceSoapServiceLocator please help me.
I have a question. Which one these methods are web method?.How can i assign methods like webmethod ?
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
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!
Address, Phones are different entities. You need to call the respective web service for this entities.
Great post, but you could also post it in the liferay.com forums to put a link to this blog.
Link is posted for few replies in the forumns. Let me know any specific thread you want me to place it. i will be happy to do that. In Liferay.com i post as http://www.liferay.com/web/arvind/profile
Thank
You could reference this post from this WIKI entry. They are related to each other:
http://www.liferay.com/es/community/wiki/-/wiki/Main/Creating+Liferay+6+plugin+web+service
Pingback: RE: Cómo generar Web Services a partir de servicios del Service Builder Lif - Foros - Liferay.com
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();
}
}
}
Pingback: Web Services In Liferay - Blogs - Youngsoft
Pingback: RE: WebService in liferay6 - Forums - Liferay.com
Hi Arvind,
I have created webservice client for blog in liferay6 as URL below
http://localhost:8080/tunnel-web/axis/Portlet_Blogs_BlogsEntryService?wsdl
I am getting an exception permission checker in not intalized.
Is Anything Going Wrong In the URL???
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
abc:abc is the username:password to connect to portal.
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.
Which version of liferay are you using ?
Liferay 6 and earlier , webservices can be listed at -> http://localhost:8080/tunnel-web/axis
Liferay 6.1, webservices can be listed at -> http://localhost:8080/api/axis
Please check your portal.properties to see the IP from which Client is making is call is allowed to do so on server side. the property which needs to be set is axis.servlet.hosts.allowed
-Thanks
Arvind
HI Arvind, My service builder is not generating ServiceLocator class. Olease help me.
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();
}
Can you post your exception trace ? Do you have @ symbol in the password you are using to connect to service.
Pingback: RE: Portlet with Web Service, store data in DB - Forums - Liferay.com
Pingback: RE: Creating portlet using Liferay with Webservices - Forums - Liferay.com
Hi Aravind,
I use the username bruno@7cogs.com and password bruno to login to Liferay. How do I specify these credentials which accessing webservice ?
Thanks,
-dingolfy
Change the authentication type to username in control panel.
I can’t change it to username as all the users use their email address to login.
Great Information, i solved my problem.
thanks all of you.
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.
You need to integrate Web Security. Basically the url to call the service should be build dynamically rather than hard coded values.
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 ?