The following tutorial demonstrates how to access web services from Java JAX-RPC.
SQL Anywhere SOAP web services that are accessed from JAX-RPC should be declared to be of format CONCRETE.
Copy the SQL Anywhere sample database from samples-dir to another location, such as c:\webserver\demo.db.
At a command prompt, execute the following statement to start a personal web server. The -xs http(port=80)
option tells the database server to accept HTTP requests. If you already have a web server running on port 80, use another port number such as 8080 for this tutorial.
dbeng10 -xs http(port=80) c:\webserver\demo.db
Start Interactive SQL and connect to the SQL Anywhere sample database as the DBA. Execute the following statements:
Define a SOAP service that lists the Employees table. You may already have done this if you performed the steps in Tutorial: Accessing web services from Microsoft .NET.
CREATE SERVICE "SASoapTest/EmployeeList" TYPE 'SOAP' AUTHORIZATION OFF SECURE OFF USER DBA AS SELECT * FROM Employees;
Because authorization has been turned off, anyone can use this service without supplying a user name and password. The commands run under user DBA. This arrangement is simple, but insecure.
Create a DISH service to act as a proxy for the SOAP service and to generate the WSDL document.
CREATE SERVICE "SASoapTest_CONCRETE" TYPE 'DISH' GROUP "SASoapTest" FORMAT 'CONCRETE' AUTHORIZATION OFF SECURE OFF USER DBA;
The SOAP and DISH service must be of format CONCRETE. In this example, the FORMAT clause was omitted when the SOAP service was created. As a result, the SOAP service inherits the CONCRETE format from the DISH service.
Take a look at the WSDL that the DISH service automatically creates. To do so, open a web browser and browse to the following URL: http://localhost:80/demo/SASoapTest_CONCRETE. The DISH service automatically generates a WSDL document that appears in the browser window.
In particular, observe the SimpleDataset object that is exposed because the format of this service is CONCRETE. In a later step, the wscompile application uses this information to generate a SOAP 1.1 client interface for this service.
<types> <s:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace= "http://localhost/demo/SASoapTest_CONCRETE"> <s:import namespace="http://www.w3.org/2001/XMLSchema" /> <s:complexType name="SimpleDataset"> <s:sequence> <s:element name="rowset"> <s:complexType> <s:sequence> <s:element name="row" minOccurs="0" maxOccurs="unbounded"> <s:complexType> <s:sequence> <s:any minOccurs="0" maxOccurs="unbounded" /> </s:sequence> </s:complexType> </s:element> </s:sequence> </s:complexType> </s:element> </s:sequence> </s:complexType> <s:element name="error" type="s:string" /> <s:element name="EmployeeList"> <s:complexType> <s:sequence /> </s:complexType> </s:element> <s:element name="EmployeeListResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="EmployeeListResult" type="s3:SimpleDataset" /> <s:element name="sqlcode" type="s:int" /> </s:sequence> </s:complexType> </s:element> </s:schema> </types>
In the next section of this tutorial, you access these services from Java. To do so, you need to use a Java Web Services Developer Pack available from Sun.
To download the Java JAX-RPC tools, visit http://java.sun.com/webservices/. This example was developed with Java Web Services Developer Pack 2.0 for Windows.
Set your CLASSPATH environment variable. In this example, the Java Web Services Developer Pack 2.0 and the Sun Java 1.5 JDK are installed on drive C:.
set classpath=.;c:\jdk1.5.0_06\jre\lib\rt.jar; c:\Sun\jwsdp-2.0\jaxrpc\lib\jaxrpc-api.jar; c:\Sun\jwsdp-2.0\jaxrpc\lib\jaxrpc-impl.jar; c:\Sun\jwsdp-2.0\jwsdp-shared\lib\activation.jar; c:\Sun\jwsdp-2.0\jwsdp-shared\lib\mail.jar; c:\Sun\jwsdp-2.0\saaj\lib\saaj-api.jar; c:\Sun\jwsdp-2.0\saaj\lib\saaj-impl.jar; c:\Sun\jwsdp-2.0\fastinfoset\lib\FastInfoset.jar; c:\Sun\jwsdp-2.0\sjsxp\lib\jsr173_api.jar
Set your PATH environment variable so that it includes the Java Web Services binaries, as well as the JDK. In this example, the Java Web Services Developer Pack 2.0 and the Sun Java 1.5 JDK are installed on drive C:. The binaries are located in the following directories.
c:\Sun\jwsdp-2.0\jaxrpc\bin c:\Sun\jwsdp-2.0\jwsdp-shared\bin c:\jdk1.5.0_06\bin
The next step is to create a simple XML document and compile it using wscompile. Samples of this configuration document are available from Sun. You need only replace the location attribute of the wsdl element with the URL of your DISH service. Optionally, you can also specify a package name. The package name causes the generated Java and Class files to be placed in a subdirectory of the same name.
Using a text editor, create an XML document named config.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?> <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location="http://localhost:80/demo/SASoapTest_CONCRETE" packageName="sqlanywhere" /> </configuration>
In this case, the location specified is the URL of the DISH service. In addition, the optional packageName attribute has been added so that all the generated files are placed in a new subdirectory named sqlanywhere. This is the package name for the generated class files.
At a command prompt, execute the following command.
wscompile -gen -keep config.xml
The -gen option tells wscompile to retrieve the WSDL document from the given URL and generate and compile an interface for it. The -keep option tells wscompile not to delete the .java files. Without this option, these files are deleted after the corresponding .class files have been generated. Saving these files makes it easer to examine the makeup of the interface.
Once this command completes, you should have a new subdirectory named sqlanywhere that contains the following Java files, along with the compiled .class versions of each Java file.
EmployeeList.java EmployeeListResponse.java EmployeeListResponse_LiteralSerializer.java EmployeeList_LiteralSerializer.java FaultMessage.java Row.java Rowset.java Rowset_LiteralSerializer.java Row_LiteralSerializer.java EmployeeList_LiteralSerializer.java SASoapTest_CONCRETE.java SASoapTest_CONCRETESoapPort.java SASoapTest_CONCRETESoapPort_EmployeeList_Fault_SOAPBuilder.java SASoapTest_CONCRETESoapPort_EmployeeList_Fault_SOAPSerializer.java SASoapTest_CONCRETESoapPort_Stub.java SASoapTest_CONCRETE_Impl.java SASoapTest_CONCRETE_SerializerRegistry.java SimpleDataset.java SimpleDataset_LiteralSerializer.java
Save the following Java source code into SASoapDemo.java.
// SASoapDemo.java illustrates a web service client that // calls the SASoapTest_CONCRETE service and prints out // the data. import java.util.*; import sqlanywhere.*; public class SASoapDemo { public static void main( String[] args ) { try { SASoapTest_CONCRETE_Impl service = new SASoapTest_CONCRETE_Impl(); SASoapTest_CONCRETESoapPort port = service.getSASoapTest_CONCRETESoap(); // This is the SOAP service call to EmployeeList EmployeeListResponse response = port.employeeList(); SimpleDataset result = response.getEmployeeListResult(); Rowset rowset = result.getRowset(); Row[] row = rowset.getRow(); for ( int i = 0; i < row.length; i++ ) { // Column data is contained as a SOAPElement javax.xml.soap.SOAPElement[] col = row[i].get_any(); for ( int j = 0; j < col.length; j++ ) { System.out.print(col[j].getLocalName() + "=" + col[j].getValue() + " " ); } System.out.println(); System.out.println(); } } catch (Exception x) { x.printStackTrace(); } } }
Compile SASoapDemo.java.
javac SASoapDemo.java
Run the compiled class file.
java SASoapDemo
The EmployeeList result set is displayed as column name=value pairs. Several lines of output similar to the following should be generated.
EmployeeID=102 ManagerID=501 Surname=Whitney GivenName=Fran DepartmentID=100 Street=9 East Washington Street City=Cornwall State=NY Country=USA PostalCode=02192 Phone=6175553985 Status=A SocialSecurityNumber=017349033 Salary=45700.000 StartDate=1984-08-28 TerminationDate=null BirthDate=1958-06-05 BenefitHealthInsurance=1 BenefitLifeInsurance=1 BenefitDayCare=0 Sex=F EmployeeID=105 ManagerID=501 Surname=Cobb GivenName=Matthew DepartmentID=100 Street=7 Pleasant Street City=Grimsby State=UT Country=USA PostalCode=02154 Phone=6175553840 Status=A SocialSecurityNumber=052345739 Salary=62000.000 StartDate=1985-01-01 TerminationDate=null BirthDate=1960-12-04 BenefitHealthInsurance=1 BenefitLifeInsurance=1 BenefitDayCare=0 Sex=M