Home | | Internet & World Wide Web HOW TO PROGRAM | | Internet Programming | | Web Programming | Passing an Object of a User-Defined Type to a Web Service

Chapter: Internet & World Wide Web HOW TO PROGRAM - Rich Internet Application Server Technologies - Web Services

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Passing an Object of a User-Defined Type to a Web Service

The web methods we’ve demonstrated so far each receive and return only primitive values or Strings.

Passing an Object of a User-Defined Type to a Web  Service

 

The web methods we’ve demonstrated so far each receive and return only primitive values or Strings. Web services also can receive and return objects of user-defined types—known as custom types. This section presents an EquationGenerator web service that generates random arithmetic questions of type Equation. The client is a math-tutoring desktop ap-plication in which the user selects the type of mathematical question to attempt (addition, subtraction or multiplication) and the skill level of the user—level 1 uses one-digit num-bers in each question, level 2 uses two-digit numbers and level 3 uses three-digit numbers. The client passes this information to the web service, which then generates an Equation consisting of random numbers with the proper number of digits. The client application receives the Equation, displays the sample question to the user in a Java application, allows the user to provide an answer and checks the answer to determine whether it is correct.

 

Serialization of User-Defined Types

We mentioned earlier that all types passed to and from SOAP web services must be sup-ported by SOAP. How, then, can SOAP support a type that is not even created yet? Cus-tom types that are sent to or from a web service are serialized into XML format. This process is referred to as XML serialization. The process of serializing objects to XML and deserializing objects from XML is handled for you automatically.

Requirements for User-Defined Types Used with Web Methods

 

A class that is used to specify parameter or return types in web methods must meet several requirements:

 

1.   It must provide a public default or no-argument constructor. When a web ser-vice or web service consumer receives an XML serialized object, the JAX-WS 2.0 Framework must be able to call this constructor when deserializing the object (i.e., converting it from XML back to a Java object).

 

2. Instance variables that should be serialized in XML format must have public set and get methods to access the private instance variables (recommended), or the instance variables must be declared public (not recommended).

 

3. Non-public instance variables that should be serialized must provide both set and get methods (even if they have empty bodies); otherwise, they are not serial-ized.

 

Any instance variable that is not serialized simply receives its default value (or the value provided by the no-argument constructor) when an object of the class is deserialized.

Defining Class Equation

Figure 28.19 defines class Equation. Lines 18–31 define a constructor that takes three ar-guments—two ints representing the left and right operands and a String that represents the arithmetic operation to perform. The constructor sets the leftOperand, rightOperand and operationType instance variables, then calculates the appropriate result. The no-ar-gument constructor (lines 13–16) calls the three-argument constructor (lines 18–31) and passes default values. We do not use the no-argument constructor explicitly, but the XML serialization mechanism uses it when objects of this class are deserialized. Because we pro-vide a constructor with parameters, we must explicitly define the no-argument constructor in this class so that objects of the class can be passed to or returned from web methods.

 

1    // Fig. 28.19: Equation.java

 

2    // Class Equation that contains information about an equation

 

3    package com.deitel.iw3htp4.generator;

4

15public class Equation

16{

 

17       private int leftOperand;

 

18       private int rightOperand;

 

19       private int resultValue;

 

20         private String operationType;

21          

22         // required no-argument constructor

 

23         public Equation()

{

1                   this( 0, 0, "+" );

 

2             } // end no-argument constructor

3              

6             public Equation( int leftValue, int rightValue, String type )

7             {

 

8                   leftOperand = leftValue;

 

9                   rightOperand = rightValue;

 

10                operationType = type;

23

1                   //determine resultValue

 

2                   if ( operationType.equals( "+" ) ) // addition

 

3                         resultValue = leftOperand + rightOperand;

 

4                   else if ( operationType.equals( "-" ) ) // subtraction

 

5                         resultValue = leftOperand - rightOperand;

 

6                   else // multiplication

 

7                         resultValue = leftOperand * rightOperand;

 

8             } // end three argument constructor

32

12         // method that overrides Object.toString()

 

13         public String toString()

14         {

 

15                return leftOperand + " " + operationType + " " +

 

16                      rightOperand + " = " + resultValue;

 

17         } // end method toString

39

18         // returns the left hand side of the equation as a String

 

19         public String getLeftHandSide()

20         {

 

21                return leftOperand + " " + operationType + " " + rightOperand;

 

22         } // end method getLeftHandSide

45

1             // returns the right hand side of the equation as a String

 

2             public String getRightHandSide()

3             {

 

4                   return "" + resultValue;

 

5             } // end method getRightHandSide

51

1             // gets the leftOperand

 

2             public int getLeftOperand()

3             {

 

4                   return leftOperand;

 

5             } // end method getLeftOperand

6              

7             // gets the rightOperand

 

8             public int getRightOperand()

9             {

 

10                return rightOperand;

 

11         } // end method getRightOperand

12          

13         // gets the resultValue

 

14         public int getReturnValue()

{

67                    return resultValue;

68        }           // end method getResultValue

69                               

70        // gets the       operationType

71        public String getOperationType()

72        {                      

73                    return operationType;

74        }           // end method getOperationType

75                               

76        // required      setter

77        public void     setLeftHandSide( String value )

78        {                      

79                    // empty          body

80        }           // end setLeftHandSide

81                               

82        // required      setter

83        public void     setRightHandSide( String value )

84        {                      

85                    // empty          body

86        }           // end setRightHandSide

87                               

88        // required      setter

89        public void     setLeftOperand( int value )

90        {                      

91                    // empty          body

92        }           // end method setLeftOperand

93                               

94        // required      setter

95        public void     setRightOperand( int value )

96        {                      

97                    // empty          body

98        }           // end method setRightOperand

99                               

100     // required      setter

101     public void     setReturnValue( int value )

102     {                      

103                 // empty          body

104     }           // end method setResultOperand

105                            

106     // required      setter

107     public void     setOperationType( String value )

108     {                      

109                 // empty          body

110     }           // end method setOperationType

111  } //           end class       Equation

Class Equation defines methods getLeftHandSide and setLeftHandSide (lines 41– 44 and 77–80); getRightHandSide and setRightHandSide (lines 47–50 and 83–86); getLeftOperand and setLeftOperand (lines 53–56 and 89–92); getRightOperand and setRightOperand (lines 59–62 and 95–98); getReturnValue and setReturnValue (lines 65–68 and 101–104); and getOperationType and setOperationType (lines 71–74 and 107–110). The client of the web service does not need to modify the values of the instance variables. However, recall that a property can be serialized only if it has both a get and a set accessor, or if it is public. So we provided set methods with empty bodies for each of the class’s instance variables. Method getLeftHandSide (lines 41–44) returns a String repre-senting everything to the left of the equals (=) sign in the equation, and getRightHandSide (lines 47–50) returns a String representing everything to the right of the equals (=) sign. Method getLeftOperand (lines 53–56) returns the integer to the left of the operator, and getRightOperand (lines 59–62) returns the integer to the right of the operator. Method getResultValue (lines 65–68) returns the solution to the equation, and getOperation-Type (lines 71–74) returns the operator in the equation. The client in this example does not use the rightHandSide property, but we included it so future clients can use it.

 

Creating the EquationGenerator Web Service

 

Figure 28.20 presents the EquationGenerator web service, which creates random, cus-tomized Equations. This web service contains only method generateEquation (lines 18– 31), which takes two parameters—the mathematical operation (one of "+", "-" or "*") and an int representing the difficulty level (1–3).

 

18// Fig. 28.20: Generator.java

 

19// Web service that generates random equations

 

20package com.deitel.iw3htp4.ch28.equationgenerator;

21          

25import java.util.Random;

 

26import javax.jws.WebService;

 

27import javax.jws.WebMethod;

 

28import javax.jws.WebParam;

29          

28  @WebService( name = "EquationGenerator",

 

29         serviceName = "EquationGeneratorService" )

 

30  public class EquationGenerator

31  {

 

32         private int minimum;

 

33         private int maximum;

16

33         // generates a math equation and returns it as an Equation object

 

34         @WebMethod( operationName = "generateEquation" )

 

35         public Equation  generateEquation(

 

36               @WebParam( name = "operation" ) String operation,

 

37               @WebParam( name = "difficulty" ) int difficulty )

38         {

 

39               minimum = ( int ) Math.pow( 10, difficulty - 1 );

 

40               maximum = ( int ) Math.pow( 10, difficulty );

25

26      Random randomObject = new Random();

 

27

36               return new Equation(

 

37                      randomObject.nextInt( maximum - minimum ) + minimum,

 

38                       randomObject.nextInt( maximum - minimum ) + minimum, operation );

 

39         } // end method generateEquation

 

} // end class EquationGenerator

 

Testing the EquationGenerator Web Service

 

Figure 28.21 shows the result of testing the EquationGenerator service with the Tester web page. In Part b of the figure, note that the web method’s return value is XML encoded. However, this example differs from previous ones in that the XML specifies the values for all the data of the returned XML serialized object returned. The proxy class receives this return value and deserializes it into an object of class Equation, then passes it to the client.

 

Note that an Equation object is not being passed between the web service and the client. Rather, the information in the object is being sent as XML-encoded data. Clients created using Java will take the information and create a new Equation object. Clients cre-ated on other platforms, however, may use the information differently. Readers creating clients on other platforms should check the web services documentation for the specific platform they are using, to see how their clients may process custom types.

 

Details of the EquationGenerator Web Service

Let’s examine web method generateEquation more closely. Lines 23–24 of Fig. 28.20 de-fine the upper and lower bounds of the random numbers that the method uses to generate an Equation. To set these limits, the program first calls static method pow of class Math— this method raises its first argument to the power of its second argument. Variable mini-mum’s value is determined by raising 10 to a power one less than difficulty (line 23). This calculates the smallest number with difficulty digits. If difficulty is 1, minimum is 1; if difficulty is 2, minimum is 10; and if difficulty is 3, minimum is 100. To calculate the value of maximum (the upper bound for numbers used to form an Equation), the program raises 10 to the power of the specified difficulty argument (line 24). If difficulty is 1, maximum is 10; if difficulty is 2, maximum is 100; and if difficulty is 3, maximum is 1000.

 

Lines 28–30 create and return a new Equation object consisting of two random numbers and the String operation received by generateEquation. Random method nextInt returns an int that is less than the specified upper bound. generateEquation generates operand values that are greater than or equal to minimum but less than maximum (i.e., a number with difficulty number of digits).



 

Consuming the EquationGenerator Web Service

The Math Tutor application (Fig. 28.22) uses the EquationGenerator web service. The ap-plication calls the web service’s generateEquation method to create an Equation object.

The tutor then displays the left-hand side of the Equation and waits for user input. Line 9 declares a GeneratorService instance variable that we use to obtain an EquationGener ator proxy object. Lines 10–11 declare instance variables of types EquationGenerator and Equation.

 

41// Fig. 28.22: EquationGeneratorClientJFrame.java

 

42// Math tutoring program using web services to generate equations

 

43package com.deitel.iw3htp4.ch28.equationgeneratorclient;

4

5 import javax.swing.JOptionPane;

 

6

48public class EquationGeneratorClientJFrame extends javax.swing.JFrame

49{

 

50       private EquationGeneratorService service; // used to obtain proxy

 

51         private EquationGenerator proxy; // used to access the web service

 

52         private Equation equation; // represents an equation

 

53         private int answer; // the user's answer to the question

 

54         private String operation = "+"; // mathematical operation +, - or *

 

55         private int difficulty = 1; // 1, 2 or 3 digits in each number

15

52         // no-argument constructor

 

53         public EquationGeneratorClientJFrame()

54         {

 

55               initComponents();

20

1                   try

2                   {

 

3                          // create the objects for accessing the EquationGenerator service

 

4                         service = new EquationGeneratorService();

 

5                         proxy = service.getEquationGeneratorPort();

 

6                   } // end try

 

7                   catch ( Exception ex )

8                   {

 

9                         ex.printStackTrace();

 

10               } // end catch

 

11         } // end no-argument constructors

32

 

13          // The initComponents method is autogenerated by Netbeans and is called

 

14          // from the constructor to initialize the GUI. This method is not shown

 

15         // here to save space. Open EquationGeneratorClientJFrame.java in this

 

16          // example's folder to view the complete generated code (lines 37-156).

17          

1            // obtains the difficulty level selected by the user

 

2            private void levelJComboBoxItemStateChanged(

 

3                   java.awt.event.ItemEvent evt )

4            {

 

5                   // indices start at 0, so add 1 to get the difficulty level

 

6                   difficulty = levelJComboBox.getSelectedIndex() + 1;

 

7            } // end method levelJComboBoxItemStateChanged

45

 

1            // obtains the mathematical operation selected by the user

 

2            private void operationJComboBoxItemStateChanged(

 

3                   java.awt.event.ItemEvent evt )

4            {

 

5                   String item = ( String ) operationJComboBox.getSelectedItem();

6              

1                   if ( item.equals( "Addition" ) )

 

2                         operation = "+"; // user selected addition

 

3                   else if ( item.equals( "Subtraction" ) )

 

4                         operation = "-"; // user selected subtraction

5                   else

 

6                         operation = "*"; // user selected multiplication

 

7            } // end method operationJComboBoxItemStateChanged

59

6            // checks the user's answer

 

7            private void checkAnswerJButtonActionPerformed(

 

8                   java.awt.event.ActionEvent evt )

9            {

 

10               if ( answerJTextField.getText().equals( "" ) )

11               {

 

12                      JOptionPane.showMessageDialog(

1                                this, "Please enter your answer." );

 

2                   } // end if

69

70      int userAnswer = Integer.parseInt( answerJTextField.getText() );

 

71

5                   if ( userAnswer == answer )

6                   {

 

7                         equationJLabel.setText( "" );

 

8                         answerJTextField.setText( "" );

 

9                         checkAnswerJButton.setEnabled( false );

 

10                      JOptionPane.showMessageDialog( this, "Correct! Good Job!",

7                                  "Correct", JOptionPane.PLAIN_MESSAGE );

 

8                   } // end if

9                   else

10               {

 

11                      JOptionPane.showMessageDialog( this, "Incorrect. Try again.",

18                            "Incorrect", JOptionPane.PLAIN_MESSAGE );

 

19               } // end else

 

20         } // end method checkAnswerJButtonActionPerformed

21          

23         // generates a new Equation based on user's selections

 

24         private void generateJButtonActionPerformed(

 

25               java.awt.event.ActionEvent evt )

26         {

27               try

28               {

 

29                      equation = proxy.generateEquation( operation, difficulty );

 

30                      answer = equation.getReturnValue();

 

31                      equationJLabel.setText( equation.getLeftHandSide() + " =" );

 

32                      checkAnswerJButton.setEnabled( true );

 

} // end try

29               catch ( Exception e )

30               {

1                          e.printStackTrace();

 

2                    } // end catch

 

3             } // end method generateJButtonActionPerformed

4              

7             // begins program execution

 

8             public static void main( String args[] )

9             {

 

10                java.awt.EventQueue.invokeLater(

 

11                      new Runnable()

12                      {

 

13                             public void run()

14                             {

112              new EquationGeneratorClientJFrame().setVisible( true );

 

13                             } // end method run

 

14                      } // end anonymous inner class

 

15                ); // end call to java.awt.EventQueue.invokeLater

 

16         } // end method main

117

18         // Variables declaration - do not modify

 

19         private javax.swing.JLabel answerJLabel;

 

20         private javax.swing.JTextField answerJTextField;

 

21         private javax.swing.JButton checkAnswerJButton;

 

22         private javax.swing.JLabel equationJLabel;

 

23         private javax.swing.JButton generateJButton;

 

24         private javax.swing.JComboBox levelJComboBox;

 

25         private javax.swing.JLabel levelJLabel;

 

26         private javax.swing.JComboBox operationJComboBox;

 

27         private javax.swing.JLabel operationJLabel;

 

28         private javax.swing.JLabel questionJLabel;

 

29         // End of variables declaration

 

} // end class EquationGeneratorClientJFrame



 

After displaying an equation, the application waits for the user to enter an answer. The default setting for the difficulty level is One-digit numbers, but the user can change this by choosing a level from the Choose level JComboBox. Clicking any of the levels invokes levelJComboBoxItemStateChanged (lines 158–163), which sets the variable difficulty to the level selected by the user. Although the default setting for the question type is Addi-tion, the user also can change this by selecting an operation from the Choose operation JComboBox. Doing so invokes operationJComboBoxItemStateChanged (lines 166–177), which sets the String operation to the appropriate mathematical symbol.

 

When the user clicks the Generate Equation JButton, method generateButton-ActionPerformed (lines 207–221) invokes the EquationGenerator web service’s generateEquation (line 212) method. After receiving an Equation object from the web service, the handler displays the left-hand side of the equation in equationJLabel (line 214) and enables the checkAnswerJButton so that the user can submit an answer. When the user clicks the Check Answer JButton, method checkAnswerJButtonActionPerformed (lines 180–204) determines whether the user provided the correct answer.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.