Creating, Publishing, Testing and Describing a Web Service
The following subsections demonstrate how to create, publish and test a HugeInteger web service that performs calculations with positive integers up to 100 digits long (maintained as arrays of digits). Such integers are much larger than Java’s integral primitive types can represent. The HugeInteger web service provides methods that take two “huge integers” (represented as Strings) and determine their sum, their difference, which is larger, which is smaller or whether the two numbers are equal. These methods will be services available to other applications via the web—hence the term web services.
1. Creating a Web Application Project and Adding a Web Service Class in Netbeans
When you create a web service in Netbeans, you focus on the web service’s logic and let the IDE handle the web service’s infrastructure. To create a web service in Netbeans, you first create a Web Application project. Netbeans uses this project type for web services that are invoked by other applications.
Creating a Web Application Project in Netbeans
To create a web application, perform the following steps:
1. Select File > New Project to open the New Project dialog.
2. Select Web from the dialog’s Categories list, then select Web Application from the Projects list. Click Next >.
3. Specify the name of your project (HugeInteger) in the Project Name field and specify where you’d like to store the project in the Project Location field. You can click the Browse button to select the location.
1 Select Sun Java System Application Server 9 from the Server drop-down list.
2 Select Java EE 5 from the J2EE Version drop-down list.
6. Click Finish to dismiss the New Project dialog.
This creates a web application that will run in a web browser, similar to the Visual Web Application projects used in Chapters 26 and 27. Netbeans generates additional files to support the web application. This chapter discusses only the web-service-specific files.
Adding a Web Service Class to a Web Application Project
Perform the following steps to add a web service class to the project:
1.In the Projects tab in Netbeans, right click the HugeInteger project’s node and se-lect New > Web Service… to open the New Web Service dialog.
2. Specify HugeInteger in the Web Service Name field.
3. Specify com.deitel.iw3htp4.ch28.hugeinteger in the Package field.
4. Click Finish to dismiss the New Web Service dialog.
The IDE generates a sample web service class with the name you specified in Step 2. You can find this class in the Projects tab under the Web Services node. In this class, you’ll de-fine the methods that your web service makes available to client applications. When you eventually build your application, the IDE will generate other supporting files (which we’ll discuss shortly) for your web service.
2. Defining the HugeInteger Web Service in Netbeans
Figure 28.2 contains the HugeInteger web service’s code. You can implement this code yourself in the HugeInteger.java file created in Section 28.3.1, or you can simply replace the code in HugeInteger.java with a copy of our code from this example’s folder. You can find this file in the project’s src\java\com\deitel\iw3htp4\ch28\hugeinteger folder. The book’s examples can be downloaded from www.deitel.com/books/iw3htp4/.
202 // Fig. 28.2: HugeInteger.java
203 // HugeInteger web service that performs operations on large integers.
204 package com.deitel.iw3htp4.ch28.hugeinteger;
1 import javax.jws.WebService; // program uses the annotation @WebService
2 import javax.jws.WebMethod; // program uses the annotation @WebMethod
3 import javax.jws.WebParam; // program uses the annotation @WebParam
6 @WebService( // annotates the class as a web service
7 name = "HugeInteger", // sets class name
8 serviceName = "HugeIntegerService" ) // sets the service name
9 public class HugeInteger
11 private final static int MAXIMUM = 100; // maximum number of digits
12 public int number = new int[ MAXIMUM ]; // stores the huge integer
9 // returns a String representation of a HugeInteger
10 public String toString()
12 String value = "";
18 // convert HugeInteger to a String
19 for ( int digit : number )
20 value = digit + value; // places next digit at beginning of value
21 // locate position of first non-zero digit
22 int length = value.length();
23 int position = -1;
1 for ( int i = 0; i < length; i++ )
3 if ( value.charAt( i ) != '0' )
34 position = i; // first non-zero digit
8 } // end for
1 return ( position != -1 ? value.substring( position ) : "0" );
2 } // end method toString
6 // creates a HugeInteger from a String
7 public static HugeInteger parseHugeInteger( String s )
9 HugeInteger temp = new HugeInteger();
10 int size = s.length();
14 for ( int i = 0; i < size; i++ )
15 temp.number[ i ] = s.charAt( size - i - 1 ) - '0';
17 return temp;
18 } // end method parseHugeInteger
22 // WebMethod that adds huge integers represented by String arguments
23 @WebMethod( operationName = "add" )
24 public String add( @WebParam( name = "first" ) String first,
25 @WebParam( name = "second" ) String second )
27 int carry = 0; // the value to be carried
28 HugeInteger operand1 = HugeInteger.parseHugeInteger( first );
29 HugeInteger operand2 = HugeInteger.parseHugeInteger( second );
30 HugeInteger result = new HugeInteger(); // stores addition result
1 // perform addition on each digit
2 for ( int i = 0; i < MAXIMUM; i++ )
4 // add corresponding digits in each number and the carried value;
5 // store result in the corresponding column of HugeInteger result
result.number[ i ] =
70 ( operand1.number[ i ] + operand2.number[ i ] + carry ) % 10;
6 // set carry for next column
7 carry =
9 ( operand1.number[ i ] + operand2.number[ i ] + carry ) / 10;
10 } // end for
21 return result.toString();
22 } // end WebMethod add
23 // WebMethod that subtracts integers represented by String arguments
24 @WebMethod( operationName = "subtract" )
25 public String subtract( @WebParam( name = "first" ) String first,
26 @WebParam( name = "second" ) String second )
28 HugeInteger operand1 = HugeInteger.parseHugeInteger( first );
29 HugeInteger operand2 = HugeInteger.parseHugeInteger( second );
30 HugeInteger result = new HugeInteger(); // stores difference
191 // subtract bottom digit from top digit
192 for ( int i = 0; i < MAXIMUM; i++ )
194 // if the digit in operand1 is smaller than the corresponding
195 // digit in operand2, borrow from the next digit
if ( operand1.number[ i ] < operand2.number[ i ] )
95 operand1.borrow( i );
97 // subtract digits
98 result.number[ i ] = operand1.number[ i ] - operand2.number[ i ];
99 } // end for
101 return result.toString();
102 } // end WebMethod subtract
209 // borrow 1 from next digit
210 private void borrow( int place )
212 if ( place >= MAXIMUM )
213 throw new IndexOutOfBoundsException();
214 else if ( number[ place + 1 ] == 0 ) // if next digit is zero
215 borrow( place + 1 ); // borrow from next digit
212 number[ place ] += 10; // add 10 to the borrowing digit
213 --number[ place + 1 ]; // subtract one from the digit to the left
214 } // end method borrow
231 // WebMethod that returns true if first integer is greater than second
232 @WebMethod( operationName = "bigger" )
233 public boolean bigger( @WebParam( name = "first" ) String first,
234 @WebParam( name = "second" ) String second )
236 try // try subtracting first from second
238 String difference = subtract( first, second );
239 return !difference.matches( "^+$" );
240 } // end try
241 catch ( IndexOutOfBoundsException e ) // first is less than second
243 return false;
244 } // end catch
245 } // end WebMethod bigger
132 // WebMethod that returns true if the first integer is less than second
133 @WebMethod( operationName = "smaller" )
134 public boolean smaller( @WebParam( name = "first" ) String first,
135 @WebParam( name = "second" ) String second )
137 return bigger( second, first );
138 } // end WebMethod smaller
140 // WebMethod that returns true if the first integer equals the second
141 @WebMethod( operationName = "equals" )
142 public boolean equals( @WebParam( name = "first" ) String first,
143 @WebParam( name = "second" ) String second )
145 return !( bigger( first, second ) || smaller( first, second ) );
146 } // end WebMethod equals
147 } // end class HugeInteger
Fig. 28.2 | HugeInteger web service that performs operations on large integers.
Lines 5–7 import the annotations used in this example. By default, each new web ser-vice class created with the JAX-WS APIs is a POJO (plain old Java object), meaning that—unlike prior Java web service APIs—you do not need to extend a class or implement an interface to create a web service. When you compile a class that uses these JAX-WS 2.0 annotations, the compiler creates all the server-side artifacts that support the web ser vice—that is, the compiled code framework that allows the web service to wait for client requests and respond to those requests once the service is deployed on an application server. Popular application servers that support Java web services include the Sun Java System Application Server ( www.sun.com/software/products/appsrvr/index.xml), GlassFish (glassfish.dev.java.net), Apache Tomcat (tomcat.apache.org), BEA Weblogic Server ( www.bea.com) and JBoss Application Server ( www.jboss.org/ products/jbossas). We use Sun Java System Application Server in this chapter.
Lines 9–11 contain a @WebService annotation (imported at line 5) with properties name and serviceName. The @WebService annotation indicates that class HugeInteger implements a web service. The annotation is followed by a set of parentheses containing optional elements. The annotation’s name element (line 10) specifies the name of the proxy class that will be generated for the client. The annotation’s serviceName element (line 11) specifies the name of the class that the client uses to obtain an object of the proxy class. [Note: If the serviceName element is not specified, the web service’s name is assumed to be the class name followed by the word Service.] Netbeans places the @WebService annotation at the beginning of each new web service class you create. You can then add the name and serviceName properties in the parentheses following the annotation.
Line 14 declares the constant MAXIMUM that specifies the maximum number of digits for a HugeInteger (i.e., 100 in this example). Line 15 creates the array that stores the digits in a huge integer. Lines 18–40 declare method toString, which returns a String repre-sentation of a HugeInteger without any leading 0s. Lines 43–52 declare static method parseHugeInteger, which converts a String into a HugeInteger. The web service’s methods add, subtract, bigger, smaller and equals use parseHugeInteger to convert their String arguments to HugeIntegers for processing.
HugeInteger methods add, subtract, bigger, smaller and equals are tagged with the @WebMethod annotation (lines 55, 81, 117, 133 and 141) to indicate that they can be called remotely. Any methods that are not tagged with @WebMethod are not accessible to clients that consume the web service. Such methods are typically utility methods within the web service class. Note that the @WebMethod annotations each use the operationName element to specify the method name that is exposed to the web service’s client.
Each web method in class HugeInteger specifies parameters that are annotated with the @WebParam annotation (e.g., lines 56–57 of method add). The optional @WebParam ele-ment name indicates the parameter name that is exposed to the web service’s clients.
Lines 55–78 and 81–102 declare HugeInteger web methods add and subtract. We assume for simplicity that add does not result in overflow (i.e., the result will be 100 digits or fewer) and that subtract’s first argument will always be larger than the second. The subtract method calls method borrow (lines 105–114) when it is necessary to borrow 1 from the next digit to the left in the first argument—that is, when a particular digit in the left operand is smaller than the corresponding digit in the right operand. Method borrow adds 10 to the appropriate digit and subtracts 1 from the next digit to the left. This utility method is not intended to be called remotely, so it is not tagged with @WebMethod.
Lines 117–130 declare HugeInteger web method bigger. Line 123 invokes method subtract to calculate the difference between the numbers. If the first number is less than the second, this results in an exception. In this case, bigger returns false. If subtract does not throw an exception, then line 124 returns the result of the expression
!difference.matches( "^+$" )
This expression calls String method matches to determine whether the String differ-ence matches the regular expression "^+$", which determines if the String consists only of one or more 0s. The symbols ^ and $ indicate that matches should return true only if the entire String difference matches the regular expression. We then use the log-ical negation operator (!) to return the opposite boolean value. Thus, if the numbers are equal (i.e., their difference is 0), the preceding expression returns false—the first number is not greater than the second. Otherwise, the expression returns true.
Lines 133–146 declare methods smaller and equals. Method smaller returns the result of invoking method bigger (line 137) with the arguments reversed—if first is less
than second, then second is greater than first. Method equals invokes methods bigger and smaller (line 145). If either bigger or smaller returns true, line 145 returns false, because the numbers are not equal. If both methods return false, the numbers are equal and line 145 returns true.
3. Publishing the HugeInteger Web Service from Netbeans
Now that we’ve created the HugeInteger web service class, we’ll use Netbeans to build and publish (i.e., deploy) the web service so that clients can consume its services. Netbeans handles all the details of building and deploying a web service for you. This includes cre-ating the framework required to support the web service. Right click the project name (HugeInteger) in the Netbeans Projects tab to display the pop-up menu shown in Fig. 28.3. To determine if there are any compilation errors in your project, select the Build Project option. When the project compiles successfully, you can select Deploy Project to deploy the project to the server you selected when you set up the web application in Section 28.3.1. If the code in the project has changed since the last build, selecting Deploy Project also builds the project. Selecting Run Project executes the web application. If the web application was not previously built or deployed, this option performs these tasks first. Note that both the Deploy Project and Run Project options also start the application server (in our case Sun Java System Application Server) if it is not already running. To ensure that all source-code files in a project are recompiled during the next build operation, you can use the Clean Project or Clean and Build Project options. If you have not already done so, select Deploy Project now.
4. Testing the HugeInteger Web Service with Sun Java System Application Server’s Tester Web page
The next step is to test the HugeInteger web service. We previously selected the Sun Java System Application Server to execute this web application. This server can dynamically
create a web page for testing a web service’s methods from a web browser. To enable this capability:
1. Right click the project name (HugeInteger) in the Netbeans Projects tab and se-lect Properties from the pop-up menu to display the Project Properties dialog.
2. Click Run under Categories to display the options for running the project.
3. In the Relative URL field, type /HugeIntegerService?Tester.
4. Click OK to dismiss the Project Properties dialog.
The Relative URL field specifies what should happen when the web application executes. If this field is empty, then the web application’s default JSP displays when you run the project. When you specify /HugeIntegerService?Tester in this field, then run the project, Sun Java System Application Server builds the Tester web page and loads it into your web browser. Figure 28.4 shows the Tester web page for the HugeInteger web ser-vice. Once you’ve deployed the web service, you can also type the URL
in your web browser to view the Tester web page. Note that HugeIntegerService is the name (specified in line 11 of Fig. 28.2) that clients, including the Tester web page, use to access the web service.
To test HugeInteger’s web methods, type two positive integers into the text fields to the right of a particular method’s button, then click the button to invoke the web method and see the result. Figure 28.5 shows the results of invoking HugeInteger’s add method with the values 99999999999999999 and 1. Note that the number 99999999999999999 is larger than primitive type long can represent.
Note that you can access the web service only when the application server is running. If Netbeans launches the application server for you, it will automatically shut it down when you close Netbeans. To keep the application server up and running, you can launch it independently of Netbeans before you deploy or run web applications in Netbeans. For Sun Java System Application Server running on Windows, you can do this by selecting
Start > All Programs > Sun Microsystems > Application Server PE 9 > Start Default Server.
To shut down the application server, you can select the Stop Default Server option from the same location.
Testing the HugeInteger Web Service from Another Computer
If your computer is connected to a network and allows HTTP requests, then you can test the web service from another computer on the network by typing the following URL (where host is the hostname or IP address of the computer on which the web service is de-ployed) into a browser on another computer:
Note to Windows XP Service Pack 2 and Windows Vista Users
For security reasons, computers running Windows XP Service Pack 2 or Windows Vista do not allow HTTP requests from other computers by default. If you wish to allow other computers to connect to your computer using HTTP, perform the following steps on Windows XP SP2:
1.Select Start > Control Panel to open your system’s Control Panel window, then double click Windows Firewall to view the Windows Firewall settings dialog.
2. In the Windows Firewall dialog, click the Exceptions tab, then click Add Port… and add port 8080 with the name SJSAS.
3. Click OK to dismiss the Windows Firewall settings dialog.
To allow other computers to connect to your Windows Vista computer using HTTP, per-form the following steps:
1. Open the Control Panel, switch to Classic View and double click Windows Firewall to open the Windows Firewall dialog.
2. In the Windows Firewall dialog click the Change Settings… link.
3. In the Windows Firewall dialog, click the Exceptions tab, then click Add Port… and add port 8080 with the name SJSAS.
4. Click OK to dismiss the Windows Firewall settings dialog.
5. Describing a Web Service with the Web Service Description Language (WSDL)
Once you implement a web service, compile it and deploy it on an application server, a client application can consume the web service. To do so, however, the client must know where to find the web service and must be provided with a description of how to interact with the web service—that is, what methods are available, what parameters they expect and what each method returns. For this purpose, JAX-WS uses the Web Service Descrip-tion Language (WSDL)—a standard XML vocabulary for describing web services in a platform-independent manner.
You do not need to understand the details of WSDL to take advantage of it—the application server software (SJSAS) generates a web service’s WSDL dynamically for you, and client tools can parse the WSDL to help create the client-side proxy class that a client uses to access the web service. Since the WSDL is created dynamically, clients always receive a deployed web service’s most up-to-date description. To view the WSDL for the HugeInteger web service (Fig. 28.6), enter the following URL in your browser:
or click the WSDL File link in the Tester web page (shown in Fig. 28.4).
Accessing the HugeInteger Web Service’s WSDL from Another Computer
Eventually, you’ll want clients on other computers to use your web service. Such clients need access to the web service’s WSDL, which they would access with the following URL:
where host is the hostname or IP address of the computer on which the web service is de-ployed. As we discussed in Section 28.3.4, this will work only if your computer allows HTTP connections from other computers—as is the case for publicly accessible web and application servers.
Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.