Web Services in Your Own Language: Part 4 – Java SOAP Client

bsoremsugar —  March 23, 2011 — 6 Comments

Editor’s Note: This is the long lost Part 4 of our series to show how to use our SugarCRM web services with various different languages. In this part, Hila Shemer will show how to use Apache Axis to connect to our SOAP services with Java. Stay tuned for more examples for other langugaes in future posts.

Today, I’ll walk you through the setup of a Java SugarCRM SOAP client based on the Apache Axis framework. Later, we’ll also look at some examples of basic things you might want to do with the client, such as logging in, creating and retrieving entries.

There are several ways to create a SOAP client that can talk to a web service in Java, but easiest and the most common way (at least based on our developer forum) is by using the Apache Axis framework to make all the initial configurations for us.

Apache Axis is a “SOAP engine”. It will help us transform the WSDL for our deployed Sugar service to a client stub and data types we can work with in Java and take care of connecting us to the service’s entry point. I should mention that Axis is more known and used for creating and publishing web services, which is not really relevant for our tutorial, but still worth mentioning.

This tutorial will walk you through the following steps:

1.     Getting Axis – Downloading Axis.

2.     Generating the client stub – Using the libraries and tools provided by the Axis framework to generate a Java client stub class and other data types.

3.     Creating and configuring the Java Project – Taking care of all the configurations from the Java side.

4.     Writing the Client code – Sample code and explanations on how to login to the application, create and retrieve an entry.

5.     Summary


1.Getting Axis

We are going to use Axis1.4 throughout the tutorial. Axis1.x is not the most recent version, but it’s the version we recommend using to generate the Sugar client. Go ahead and download it from Apache: http://ws.apache.org/axis/java/releases.html

2. Generating the client stub

In this part, we’ll use the libraries and tools provided by the Axis framework to generate a Java client stub class and other data types. Unzip the contents of the zip file anywhere and take a look at the jar files inside the ‘lib’ folder. We’ll be adding these to an AXIS classpath variable.

2.a) Create AXIS_HOME and AXIS_LIB environment variables:

export AXIS_HOME = <axis-1_4 folder location>

export AXIS_LIB=$AXIS_HOME/lib

2.b) Create AXISCLASSPATH environment variable and add jar files from $AXIS_LIB to $AXISCLASSPATH:

export AXISCLASSPATH=create constants$AXISCLASSPATH:$AXIS_LIB/axis-ant.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/commons-discovery-0.2.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/commons-logging-1.0.4.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/jaxrpc.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/log4j-1.2.8.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/saaj.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/wsdl4j-1.5.1.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/activation.jar

export AXISCLASSPATH=$AXISCLASSPATH:$AXIS_LIB/mail-1.4.1.jar

Note: If you don’t have all the jars on the list, you can search and download them at findjar. Download the missing jars into $AXIS_LIB and add them to the $AXISCLASSPATH. Make sure to use the “$AXISCLASSPATH = $AXISCLASSPATH:<new jar location>” command so you don’t wipe out everything in there!

2.c) Locate your instance of the Sugar SOAP WSDL. It should be on this location: http://<your local sugar application instance>/build/rome/builds/ent/sugarcrm/service/v3/soap.php?wsdl

It’s crucial that you have the correct location of the WSDL. Just to be on the safe side, try to open the page on your web browser and make sure you have the correct address.

2.d) Generate the client from the WSDL. We’ll be using the WSDL2JAVA tool provided by AXIS. It will use the definitions in the WSDL to create the stub, data types, and communications configurations to talk to the Sugar web service.

In your $AXIS_HOME folder, enter the following:

java -cp $AXISCLASSPATH org.apache.axis.wsdl.WSDL2Java <your local .wsdl location>

For instance, this is how I run it on my machine:

java -cp $AXISCLASSPATH org.apache.axis.wsdl.WSDL2Java http://localhost:8888/Mango/build/rome/builds/ent/sugarcrm/service/v3/soap.php?wsdl

After this is finished, you should see a new ‘com/sugarcrm/www/sugarcrm’ path created in your $AXIS_HOME folder. Inside you will find the stub and new data types generated from the WSDL. Good job!

If you’re getting a ClassNotFoundException, it means some jars may still be missing. Download them, add to $AXISCLASSPATH, and try again.

3. Creating and configuring the Java Project

In this part we are taking care of all the configurations from the Java side. Just to give you a quick idea of what that means: we are going to create a new project, import the folder we generated from the WSDL to the project, link the jars from the $AXIS_LIB to the project build path, and make sure all our configurations are correct. I will be using Eclipse 3.6.1, but this can be done in other IDEs that support Java development.

3.a) Create a New Project

Create a New Java Project and name it ‘SugarSOAPClient’.

3.b) Import the stub and data types.

We now import the stub and data types to our Java project:

  • Right click on ‘SugarSOAPClient->src’ -> Import -> select ‘file system’. Browse and select $AXIS_HOME/com. Name it ‘stub’.

import the generated 'com' folder to the project

To ensure compatibility of the package name, rename the package inside ‘stub’ to ‘com.sugarcrm.www.sugarcrm’:

  • Right click on ‘SugarSOAPClient->stub->sugarcrm.www.sugarcrm’ -> refactor ->rename -> type ‘com.sugarcrm.www.sugarcrm’.

Rename package

The package explorer should look like this:

Package explorer after the import

3.c) Link Axis Libraries to Proejct

Right click on ‘SugarSOAPClient’ -> ‘Build Path’ -> ‘Configure Build Path’ -> ‘Libraries’ -> ‘Add external jars’ -> Browse to $AXIS_HOME/lib and choose all of the jars.

jars files to add to build path

3.d) Check the generated local Sugar instance location in the Stub class.

Sometimes the WSDL2JAVA doesn’t use the correct Sugar local instance location and your client will try connecting to an invalid endpoint.

  • Open the stub class, SugarsoapBinding.java, and look for all the places where you local instance is mentioned.
  • The easiest way is to do a text ‘Find’ for ‘localhost’ and replace the text everywhere in order to fix it.

 

4. Writing the Client Code

Now we are finally ready to write the code for the client. We will create a SugarsoapBindingStub object, which includes all the operations necessary for interacting with the web service. Using the stub, we will login to the application, add a new Contact and retrieve it.

4.a) Under ‘SugarSOAPClient->src’ create a new Java Class and name it ‘SOAPClient’.

4.b) Create constants

The first thing we’ll do is creating some constants that we’ll use later in the program. You should replace ‘ENDPOINT_URL’ (WSDL location), ‘USER_NAME’ and ‘PASSWORD’ (MD5 format):

4.c) Add main function and setup the Endpoint to which the stub client will attempt to connect:

4.d) Below the end point creation, write the code to create the stub object. The stub’s Constructor takes the endpoint URL we defined earlier and a new org.apache.axis.client.Service object :

4.e)Now we are ready to login to the Sugar application. In order to login, we first need to create and set all the arguments that serve as parameters to the method. The parameters for login are a User_auth object, containing the user name and password, the application name, and an array of Name_values, which are mappings of names to values. Sending an array of Name_value to login will allow us to set some initial settings such as ‘language’ and ‘notifyonsave’, but since these are optional, we’re not going to worry about it and just pass an empty array.

If your client fails to login, make sure the address for your local Sugar instance in the SugarsoapBinidingStub class is correct.

4.f) After we’ve successfully logged in to the application, it’s time to make some changes. We are going to add a new Contact to the contacts module. The set_entry method takes as parameters a session id, which was returned by the login method, a module name, and a Name_value array, which defines the names and values for the new Contact we create.

After the new Contact has been created, it’s a good idea to go to your local Sugar application and make sure that the contact was actually created in the system and has all the correct fields.

4.g) Now let’s get that new contact back from the application. We’re going to use get_entry, which takes the as parameters the following: session id (returned from login), module name, SugarBean id (returned from set_entry), a select fields array (allows us to select which fields to return. We want all of them, so we’ll leave it empty), and link_name_to_fields_array (also optional if you want to link returned fields to specific names).

get_entry returns an entry_list, which contains a Name_value array with all the information about the Contact. We will output this Name_value array.

5. Summary

In this tutorial, we learned how to set up and write a Java SOAP client based on the Apache Axis framework. We walked through some code samples that demonstrate basic things you might want to do with the client such as login, get_entry, and set_entry. I hope this will make it easier for those interested in building a Java client for the SugarCRM web service. Please leave comments if you have any questions.

6 responses to Web Services in Your Own Language: Part 4 – Java SOAP Client

  1. 

    Here I got this to work in .Net
    using System; System;using System.Collections.Generic; System.Collections.Generic;using System.Text; System.Text;using System.Security.Cryptography; System.Security.Cryptography;namespace testSugarSoap{class Program testSugarSoap{class Programclass Program{static crmzV4.sugarsoap sugarSoap = new crmzV4.sugarsoap();static crmzV4.user_auth userAuth = new crmzV4.user_auth();static crmzV4.name_value[] nameValue = new crmzV4.name_value[1];static crmzV4.entry_value entryValue = new crmzV4.entry_value();static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;static crmzV4.sugarsoap sugarSoap = new crmzV4.sugarsoap();static crmzV4.user_auth userAuth = new crmzV4.user_auth();static crmzV4.name_value[] nameValue = new crmzV4.name_value[1];static crmzV4.entry_value entryValue = new crmzV4.entry_value();static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;static crmzV4.user_auth userAuth = new crmzV4.user_auth();static crmzV4.name_value[] nameValue = new crmzV4.name_value[1];static crmzV4.entry_value entryValue = new crmzV4.entry_value();static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;static crmzV4.name_value[] nameValue = new crmzV4.name_value[1];static crmzV4.entry_value entryValue = new crmzV4.entry_value();static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;static crmzV4.entry_value entryValue = new crmzV4.entry_value();static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;static void Main(string[] args){con(sugarSoap.SoapVersion.ToString());userAuth.user_name = “bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;”bdefranco”;userAuth.password = getMd5Hash(“proxima”);//sugarSoap.SoapVersion = “1.0″;”proxima”);//sugarSoap.SoapVersion = “1.0″;//sugarSoap.SoapVersion = “1.0″;//nameValue[0].name = “”;//nameValue[0].name = “”;//nameValue[0].value = “”;//nameValue[0].value = “”;nameValue = null;entryValue = sugarSoap.login(userAuth,”SugarCRM”,nameValue);con(entryValue.id);con(entryValue.module_name); Console.ReadLine();sugarSoap.logout(entryValue.id);} static string getMd5Hash(string input){// Create a new instance of the MD5CryptoServiceProvider object.null;entryValue = sugarSoap.login(userAuth,”SugarCRM”,nameValue);con(entryValue.id);con(entryValue.module_name); Console.ReadLine();sugarSoap.logout(entryValue.id);} static string getMd5Hash(string input){// Create a new instance of the MD5CryptoServiceProvider object.”SugarCRM”,nameValue);con(entryValue.id);con(entryValue.module_name); Console.ReadLine();sugarSoap.logout(entryValue.id);} static string getMd5Hash(string input){// Create a new instance of the MD5CryptoServiceProvider object.Console.ReadLine();sugarSoap.logout(entryValue.id);} static string getMd5Hash(string input){// Create a new instance of the MD5CryptoServiceProvider object.static string getMd5Hash(string input){// Create a new instance of the MD5CryptoServiceProvider object.// Create a new instance of the MD5CryptoServiceProvider object.MD5 md5Hasher = MD5.Create();// Convert the input string to a byte array and compute the hash.MD5 md5Hasher = MD5.Create();// Convert the input string to a byte array and compute the hash.// Convert the input string to a byte array and compute the hash.byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));// Create a new Stringbuilder to collect the bytesbyte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));// Create a new Stringbuilder to collect the bytes// Create a new Stringbuilder to collect the bytes// and create a string.// and create a string.StringBuilder sBuilder = new StringBuilder();// Loop through each byte of the hashed data StringBuilder sBuilder = new StringBuilder();// Loop through each byte of the hashed data // Loop through each byte of the hashed data // and format each one as a hexadecimal string.// and format each one as a hexadecimal string.for (int i = 0; i < data.Length; i++){sBuilder.Append(data[i].ToString("x2"));}// Return the hexadecimal string.for (int i = 0; i < data.Length; i++){sBuilder.Append(data[i].ToString("x2"));}// Return the hexadecimal string."x2"));}// Return the hexadecimal string.// Return the hexadecimal string.return sBuilder.ToString();} static void con(string inp){Console.WriteLine(inp);}} –Bryan DeFrancoreturn sBuilder.ToString();} static void con(string inp){Console.WriteLine(inp);}} –Bryan DeFrancostatic void con(string inp){Console.WriteLine(inp);}} –Bryan DeFrancoConsole.WriteLine(inp);}} –Bryan DeFranco

  2. 

    That code posted like crap; it looks like it duplicated many lines & I the edit button Not working.  Hopefully someone can get something useful still.

  3. 

    Hey i got error on Sugarsoaplocator.java file.
    Error is like

    Multiple markers at this line
    – The serializable class SugarsoapLocator does not declare a static final serialVersionUID field of
    type long
    – The hierarchy of the type SugarsoapLocator is inconsistent

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s