Srikanth Technologies

Consuming .NET Web Service from Java

In this blog, I want to show you a couple of things about Web Services. Here is the list of things on my mind.

Creating a web service

First let us create a new project in Visual Studio.NET for web service. Then add classes related to data access and write code for Web Service methods.
  1. Start Visual studio.NET 2008/2005
  2. Select File->New->Website. Select ASP.NET Web service as the type of the project and enter InventoryWS as the name of the project. Visual Studio provides Service.cs and Service.asmx files along with others. Delete these two files.
  3. We add a new web service to the project using Website -> Add new item -> Web Service and enter name as InventoryService. Visual Studio creates InventoryService.aspx in root directory and InventoryService.cs in App_Code directory.
We will write code for web service later. First let us create DAL to access database.

Creating Data Access Layer

Data Access Layer is set of classes used to access database. We centralize the entire data access to DAL. In this project we create two classes to represent data.

I am using PRODUCTS table, which is created by me in MSDB database of Sql Server Express Edition. You have to do the same in your system. Create PRODUCTS table with the following structure.

PRODID    - int  (Primary key)
prodname  - varchar(50)
price     - money
qoh       - int
remarks   - varchar(200)
catcode   - varchar(10)

Add some rows to PRODUCTS table.

Add a class to the project using Website-> Add New Item -> Class and enter name as Product. Here is the code for Product.cs.

using System;
using System.Web.Services;
using System.Runtime.Serialization;

public class Product
{
    private int prodid, qty;    
    private string name, remarks;
    private double price;

    public int Qty
    {
        get { return qty; }
        set { qty = value; }
    }

    public int Prodid
    {
        get { return prodid; }
        set { prodid = value; }
    }

    public string Remarks
    {
        get { return remarks; }
        set { remarks = value; }
    }
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public double Price
    {
        get { return price; }
        set { price = value; }
    }
}
Add connection string in connectionStrings section of web.config as follows.
  <connectionStrings>
    <add  name="msdbcs"  connectionString="data source=localhost\sqlexpress;integrated security=true;Initial Catalog=msdb"
              providerName="System.Data.SqlClient" />
  </connectionStrings >
Add Database.cs class and enter the following code.
using System.Web.Configuration;
public class Database
{
    public static string ConnectionString
    {
        get
        {
            return WebConfigurationManager.ConnectionStrings["msdbcs"].ConnectionString;
        }
    }
}
Now create ProductDAL, which contains static methods for operations related to PRODUCTS table as follows.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
public class ProductsDAL
{
    public static List GetAllProducts()
    {
        SqlConnection con = new SqlConnection(Database.ConnectionString);
        con.Open();
        SqlCommand cmd = new SqlCommand("select * from products", con);
        SqlDataReader dr = cmd.ExecuteReader();
        List products = new List();
        while (dr.Read())
        {
            Product p = new Product();
            p.Prodid = (int)dr["prodid"];
            p.Name = dr["prodname"].ToString();
            p.Remarks = dr["remarks"].ToString();
            p.Qty = (int)dr["qoh"];
            p.Price = Convert.ToDouble(dr["price"]);
            products.Add(p);
        }
        dr.Close();
        con.Close();
        return products;
    }

    public static Product GetProduct(int prodid)
    {
        SqlConnection con = new SqlConnection(Database.ConnectionString);
        con.Open();
        SqlCommand  cmd = new SqlCommand("select * from products where prodid = @prodid", con);
        cmd.Parameters.AddWithValue("@prodid", prodid);
        SqlDataReader dr = cmd.ExecuteReader();
        if (dr.Read())
        {
            Product p = new Product();
            p.Prodid = (int) dr["prodid"];
            p.Name = dr["prodname"].ToString();
            p.Remarks = dr["remarks"].ToString();
            p.Qty = (int) dr["qoh"];
            p.Price =  Convert.ToDouble (dr["price"]);
            return p;

        }
        else  // product not found
            return null;
    }
}

Using DAL in Web Service

Now let us write code in web service, which makes use of DAL. It is always better you separate data access code into DAL so that other parts of the application do not depend on data access. They access database through DAL.

Write the following code in InventoryService.cs.

using System;
using System.Web.Services;
using System.Collections.Generic;

[WebService(Namespace = "http://www.srikanthtechnologies.com/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class InventoryService : System.Web.Services.WebService {

    [WebMethod( Description ="Returns Details Of All Products")]
    public List GetAllProducts()
    {
        return ProductsDAL.GetAllProducts();
    }

    [WebMethod(Description = "Returns Details Of A Single Product")]
    public Product GetProduct(int prodid)
    {
        return ProductsDAL.GetProduct(prodid);
    }

}

Now we are through our web service creation. Select web service - InventoryService.asmx and select View In Browser option from context menu (right click).

From the page displayed in browser, click on methods and invoke them to test them.

Custom classes and WSDL

Click on Service Description link and you get WSDL for the web service. The following section in that is of interest.
<s:complexType name="ArrayOfProduct">
  <s:sequence>
    <s:element minOccurs="0" maxOccurs="unbounded" name="Product" nillable="true" type="tns:Product" /> 
  </s:sequence>
</s:complexType>
<s:complexType name="Product">
   <s:sequence>
    <s:element minOccurs="1" maxOccurs="1" name="Qty" type="s:int" /> 
    <s:element minOccurs="1" maxOccurs="1" name="Prodid" type="s:int" /> 
    <s:element minOccurs="0" maxOccurs="1" name="Remarks" type="s:string" /> 
    <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" /> 
    <s:element minOccurs="1" maxOccurs="1" name="Price" type="s:double" /> 
   </s:sequence>
</s:complexType>

Product class is taken as complexType and its members are placed as sub elements. Collection of Products is taken as an ArrayOfProduct. When you need to access this web service from Java application, we create proxy in Java. Product element will become a class in Java and ArrayOfProduct becomes another class that contains a List of product objects. So, WSDL contains details about custom classes so that clients can generate these classes again on the client. 

Creating Proxy in Java

Now, let us create a proxy in Java to access InventoryService Web Service.
  1. Start NetBeans IDE 6.5.
  2. Select File->New Project. Select Java in category and Java Application in projects. Click on Next.
  3. Enter InventoryClient as the name of the application. Change name of the class in Create Main Class option to Client
  4. Click on Finish.
  5. Select InventoryClient project in Projects window. Right click to invoke context menu. Select New->Other. Select Web service in categories and Web Service Client in File Types.
  6. In the next window, select WSDL URL radio button (as shown below) and enter the URL at which InventoryService is running. Click on Finish. NetBeans creates required classes to access web service.

 

Write code in Java to call web service

Once proxy is created then we can write code to access web service methods from Java. In fact, NetBeans can do that for you. Follow the steps given below.
  1. Open Client.java
  2. Go into main function and click on right button. From context menu select Web Service Client Resources -> Call Web Service Operation...
  3. A window pops up with operations in the web service (shown below).

    Select GetProduct in InventoryServiceSoap12 section. NetBeans automatically writes code for you. Just assign product id 100 to prodid and change code regarding output, to complete the code.

       try { 
               // Call Web Service Operation
                com.srikanthtechnologies.InventoryService service = new com.srikanthtechnologies.InventoryService();
                com.srikanthtechnologies.InventoryServiceSoap port = service.getInventoryServiceSoap12();
                // TODO initialize WS operation arguments here
                int prodid = 100;
                // TODO process result here
                com.srikanthtechnologies.Product result = port.getProduct(prodid);
                System.out.println( result.getName());
            } catch (Exception ex) {
                // TODO handle custom exceptions here
            }
    
    Lines in bold are modified by me. The rest is provided by NetBeans. That's all you have to do to call web service created in .NET from Java.

    As you can see, NetBeans created a class Product for which information is provided in WSDL.

    Follow the same steps to call GetAllProducts method. Change the code as follows.

    try { // Call Web Service Operation
                com.srikanthtechnologies.InventoryService service = new com.srikanthtechnologies.InventoryService();
                com.srikanthtechnologies.InventoryServiceSoap port = service.getInventoryServiceSoap12();
                // TODO process result here
                com.srikanthtechnologies.ArrayOfProduct result = port.getAllProducts();
    
                List products = result.getProduct(); 
       
                for(Product p : products) {
                    System.out.println( p.getName() + " : "  + p.getPrice());
                }
    
                
            } catch (Exception ex) {
                // TODO handle custom exceptions here
            }
    
  4. Now, run Client.java to get details of products from Java program.