Web ServicesBuilding Web Services that Produce Multiple Return Values

Building Web Services that Produce Multiple Return Values

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Web service operations typically return a single value. This may not be true in all cases. So, you need a way to return multiple values from a Web service operation. This article explains the procedure for creating, exposing, and invoking a Web service with multiple return values in detail.

The aim of this article is to explain ways to return multiple values from a Web service operation. There are two ways of doing this; they are:

  1. Return type can be a Complex Data type with muliple parts or arrays.
  2. Make use of In-Out Parameters in the Web service operations.

This article concentrates on the second option of implementing it, providing a step-by-step procedure for creating a Web service and a client to access it. This article assumes that the underlying Application Server is BEA Weblogic 8.x.

Creating a Web Service with Multiple Return Values

In Weblogic, Holders can be used to make Web service operations return multiple values.The return type can be primitive or User-defined. The JAX-RPC provides Holders for Primitive data types. They are available in the javax.xml.rpc.holders package. You need to provide Holders for Complex/User defined data types.

We have taken a simple example called “Online Exam Results” service that takes a roll number as input and returns the result of ‘pass/fail’ as a String. It also returns a complex object called Student that will give details about grade, course, and name of the student.

Here is the Student type class.

package onlineResult;

public class Student
{
   String name;
   String grade;
   String course;

   public Student()
   {}

   public Student(String name,String grade,String course)
   {
      this.name = name;
      this.grade = grade;
      this.course = course;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
   public String getGrade()
   {
      return grade;
   }

   public void setGrade(String grade)
   {
      this.grade = grade;
   }
   public String getCourse()
   {
      return course;
   }

   public void setCourse(String course)
   {
      this.course = course;
   }

}

Writing the holder

The Holder that you create should be a final class named in the format “DataType” + Holder; for example, ‘StudentHolder’. StudentHolder needs to implement the javax.mxl.rpc.holders.Holder interface. The attribute defined in the class should be named ‘value’. The StudentHolder class needs to provide two constructors: a default constructor and a full constructor. The Holder class should be placed in a directory called ‘holders’ under the directory where the User-defined data type class exists. In this example, the StudentHolder class is placed in the ‘holders’ directory, which is under the ‘OnlineResult’ directory, which contains the User-defined data type ‘Student’.

package onlineResult.holders;

import onlineResult.Student;
import javax.xml.rpc.holders.Holder;

public final class StudentHolder implements Holder
{
   public Student value;
   public StudentHolder()
   {
      value = new Student();
   }

   public StudentHolder(Student value)
   {
      this.value = value;
   }
}

Writing the service

The ExamResultService class contains a method called getResult() that returns multiple values. This may be confusing because the signature of getResult() method shows the return type as String. But here, returning multiple values is achieved by passing a parameter that acts as an input as well as output parameter. Such a parameter is called a IN-OUT parameter.

The getResult() method takes two parameters. The first parameter is a String called rollnumber, which is an input parameter; the second is of type StudentHolder, which we created in the previous step. Here, StudentHolder is an IN-OUT parameter. This StudentHolder object will get updated according to the rollnumber input. After invocation, the StudentHolder instance will contain updated values.

import onlineResult.Student;
import onlineResult.holders.*;
public class ExamResultService
{
   String result;
   Student student;
   public String getResult(String rollnumber,
                           StudentHolder studentHolder)
   {
      if(rollnumber.equals("1000"))
      {
         result = new String("Pass");
         student = new Student("Albert","S","MCA");
         studentHolder.value = student;

      }
      else if(rollnumber.equals("1001"))
      {
         result = new String("Fail");
         student = new Student("Robert","F","MSc");
         studentHolder.value = student;

      }
      else if(rollnumber.equals("1002"))
      {
         result = new String("Pass");
         student = new Student("Mary","A","BSc");
         studentHolder.value = student;

      }
      else
      {
         result = new String("No Match Found");
         student = new Student();
         studentHolder.value = student;

      }
      return result;
   }


}

Deploying

Compile ExamResultService, StudentHolder, and Student into their corresponding directories. Use the following command to create the EAR file. Before you run the command, make sure that the classpath contains the service-related classes, Weblogic.jar, and webservices.jar provided by Weblogic.

>java  weblogic.webservice.servicegen
-destEar c:Complex_inout_StudentExamResultService.ear
-warName ExamResultService.war
-javaClassComponents ExamResultService
-serviceName ExamResultService
-serviceURI /ExamResultService
-targetNamespace http://www.mes.hp.com

Running the above command will create an ExamResultService.ear file. Now, you need to deploy this EAR file into the Weblogic server. Start Weblogic server and run the following command to deploy the war in Weblogic.

>java  weblogic.Deployer
-adminurl http://localhost:7001
-user admin
-password admin
-name ExamResultService
-source c:Complex_inout_StudentExamResultService.ear
-targets myserver
-activate

Note: You need to change the values according to your service before running this command.

Now, the service is deployed successfully. You can access your service with the URL http://localhost:7001/ExamResultService/ExamResultService.

Writing the Client

The clientgen ant task can be used to generate stubs for the deployed service. Here is build.xml.

<project name="buildWebservice" default="generate-client">
   <target name="generate-client">
<clientgen wsdl="http://localhost:7001/ExamResultService/
                        ExamResultService?wsdl"
           packageName="examservice"
  clientJar="c:/nandhini/Complex_inout_Student/
                ExamResultService.jar"/>
  </target>
</project>

Running this task will generate an ExamResultService.jar file. You need to write a client using the stubs that have been generated and packed inside this JAR file. A sample client for accessing your Online Exam Results is given below. The generated JAR file needs to be set in the Classpath before compiling this client.

import examservice.*;
import javax.xml.rpc.holders.*;
import onlineResult.Student;
import onlineResult.holders.StudentHolder;

public class MyClient
{
   public static void main(String arg[])
   {
   try
      {
      ExamResultServicePort myexam = new
         ExamResultService_Impl().getExamResultServicePort();
      StudentHolder studentHolder = new StudentHolder();
      String res = myexam.getResult("1000",studentHolder);
      System.out.println("Result : "+res  );
      Student s = studentHolder.value;
      System.out.println("Name : "+s.getName()+
                         "nGrade : "+s.getGrade()+"nCourse :
                         "+s.getCourse());
      }
      catch(Exception e)
      {
         System.out.println("Exception "+e);
      }
   }
}

Running the sample client will give the following output:

>java MyClient
Result : Pass
Name : Albert
Grade : S
Course : MCA

Conclusion

We hope that this article helps you develop more useful Web services than before.

About the Authors

Nandhini Arumugam holds a Masters degree in Computer Applications from PSG College of Technology, Coimbatore. She has been working as a Software Engineer in the Telecom and Mobile Solutions Lab, Hewlett-Packard, Bangalore for more than one year. The domain of her experience includes Web services and J2EE-related technologies. She can be reached at nandhini.arumugam@hp.com.

Jeyarani Venkatasamy holds a Masters degree in Computer Applications from Sri Sarada College for Women, Tirunelveli. She has been working as a Senior Sofware Engineer in the Telecom and Mobile Solutions Lab, Hewlett-Packard, Bangalore for more than one year. The domain of her experience includes Web services, Java and J2EE-related technologies. She can be reached at jeyarani.venkatasamy@hp.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories