![]() | ![]() | ![]() | ![]() |
This sample demonstrates how to create a Web service written in Java that can access SAS analytics through SAS Integration Technologies. Presenting a simple usage scenario, this sample Web service allows a user to check the credit limit for a customer given a customer name and ID number. The sample Web service will be built and deployed using the Java Web Services Developer Pack 1.5. This sample is implemented using JAX-RPC, providing support for XML, the Simple Object Access Protocol (SOAP), and Web Services Description Language (WSDL). These are the accepted industry standards that enable cross-platform interoperability between Web services and clients. The installation procedures for this sample go through all the steps to implement a Web service, build it using Ant, and then deploy it to Apache Tomcat 5.0 for Java WSDP.
To demonstrate how to call the methods on the Web service, we are providing a stand-alone Java client as well as a JavaServer Page. It is also possible to call the Web service from applications written in languages other than Java, for example from a Microsoft ASP.NET page written in C#.
This sample demonstrates how to:
The following sections explain the source code for this sample.
Web Service Description Language (WSDL) File: CreditService.wsdl
At the bottom of this page, we also provide a list of references so that you can read more about these topics.
CreditService.wsdl describes the Web service interface using the WSDL standard. The wscompile tool included with the JWSDP parses this file to generate client and server stubs enabling a Java client to call a Web service without having to implement all the low-level HTTP and Web service standards.
After installation you can view the WSDL file by going to the URL http://localhost:8080/CreditService/CreditService?WSDL. For more information on WSDL, visit the W3C site Web Service Description Language (WSDL).
CreditServiceImpl.java is the implementation of the Web service interface, CreditServiceIF. This is a very simple Web service, so there is only one method to implement, getCreditLimit. This is a very generic usage scenario, where an IWorkspace object is created using the WorkspaceFactory, with no interaction with a metadata source. A more robust usage scenario would require a workspace pool defined in LDAP that can serve connections across multiple machines. For simplicity, this sample just creates an instance of the workspace, uses it, and then releases it. The response time won't be as quick as in the pooling scenario, and there is no failover if our specified IOM Bridge server goes down. For more information about workspace pooling, see Adding Connection Pooling Features.
After a workspace is created, the SAS stored process is run to determine the customer's credit limit. Using the StoredProcessService interface, GetCreditLimit is executed passing in the customer name and customer ID number as parameters. For debugging purposes the SAS log is then printed to System.out. The log output can be viewed in the logs folder in the file catalina.out. After the stored process executes, a data set is created that contains the customer's credit limit. We get the results by accessing the data set WORK.OUT using JDBC. If there was an error executing the stored process we will get no records from the data set, so a default value of 0 is returned if there are no records in the data set. A more robust implementation would throw an exception that would indicate the reason for the failure, such as invalid customer ID number. In a finally block, which ensures we clean up regardless of exceptions, the JDBC connection and SAS Workspace are closed if they were created, and the WorkspaceFactory is shutdown.
package sas.web.svc.samples;
import java.util.Properties;
import com.sas.iom.SAS.IWorkspace;
import com.sas.iom.SAS.IWorkspaceHelper;
import com.sas.iom.SAS.*;
import com.sas.iom.*;
import com.sas.rio.MVAConnection;
public class CreditServiceImpl implements CreditServiceIF, java.rmi.Remote {
public double getCreditLimit(java.lang.String custName, java.lang.String custID)
throws java.rmi.RemoteException {
/* Here's the place to put some validation code */
double _retVal = 0;
/* Define a connection to a SAS IOM server via a iWorkspace object */
try {
WorkspaceFactory wsf = new WorkspaceFactory();
Properties serverInfo = new Properties();
serverInfo.put("host", "localhost");
serverInfo.put("port", "5307");
serverInfo.put("userName", "username");
serverInfo.put("password", "password");
IWorkspace iWorkspace = wsf.createWorkspaceByServer(serverInfo);
/* Use the StoredProcessService to execute the SAS code */
ILanguageService iLang = iWorkspace.LanguageService();
IStoredProcessService iSP = iLang.StoredProcessService();
iSP.Repository("file:c:\\SASRepository");
iSP.Execute("GetCreditLimit", "custname" + "=" + custName
+ " custid=" + custID + " outData=work.out");
/* Print out SAS log for debugging.
Output is in /logs/catalina.out. */
String log = iLang.FlushLog(50000);
System.out.println(log);
/* Read the result via an MVAConnection */
IDataService iDataService = iWorkspace.DataService();
java.sql.Connection connection = new MVAConnection(iDataService,
new Properties());
java.sql.Statement statement = connection.createStatement();
java.sql.ResultSet rs = statement.executeQuery(
"Select * from work.out");
/* Get the credit limit and return it to the calling client */
if( rs.next() )
{
String creditLimit = rs.getString("creditLimit");
_retVal = Double.parseDouble(creditLimit);
}
}
catch( Throwable t ) {
t.printStackTrace();
java.rmi.RemoteException ex =
new java.rmi.RemoteException("Error getting credit limit", t);
throw ex;
}
finally {
try{
/* Close JDBC connection if open */
if(connection != null)
{
if(!connection.isClosed())
connection.close();
}
/* Close iWorkspace */
if(iWorkspace != null)
iWorkspace.Close();
/* Shutdown WorkspaceFactory */
if(wsf != null)
wsf.shutdown();
} catch(Throwable t) {
//t.printStackTrace();
}
}
return _retVal;
}
}
Our client is very simple because we're using JAX-RPC with supported data types double and string. If we had chosen to use a more complex data type, it would have required that we do more work to create SOAPElement objects. In this case it looks like we're just making a normal method call, with the complexities of SOAP hidden by the stub classes.
First, we get a connection to the CreditService Web service by calling getCreditServiceIFPort(). This method returns a Stub that can be used to make calls on the remote Web service interface. We then cast our Stub to the CreditServiceIF interface. We can then call the Web service method just like any other method of a class.
package sas.web.svc.samples;
import javax.xml.rpc.Stub;
public class CreditServiceClient {
public static void main(String[] args) {
if(args.length < 2)
System.out.print("Usage: java sas.web.svc.samples.CreditServiceClient ");
System.out.println("<customername> <customeridnumber>");
else
{
try {
Stub stub = (Stub)(new CreditService_Impl().getCreditServiceIFPort());
CreditServiceIF cs = (CreditServiceIF)stub;
System.out.print("Customer Name: ");
System.out.println(args[0]);
System.out.print("Customer ID #: ");
System.out.println(args[1]);
System.out.println("Getting credit limit....please wait.");
double result = cs.getCreditLimit(args[0], args[1]);
System.out.print("Credit Limit: ");
System.out.println(result);
} catch (Exception ex) {
//System.out.println(ex.message);
ex.printStackTrace();
}
}
}
}
The JSP code is very similar to the code in the stand-alone client. We perform some validation of the input values to make sure that they are not null. If the input values are valid, the method is called. The following code snippet shows how the Web service is called. The rest of the code in the JSP builds the input form and reads the values from the request object.
if((id != null) && (name != null) && (name.length() > 0) && (id.length() > 0))
{
// At this point ID and name have not been validated.
// There should be some input validation here, but since this is just
// a simple sample, its just passed in as is.
out.println("<h3>Credit Limit for " + name + "(" + id + ") is ");
//Create an instance of the Stub used to call the Web service
javax.xml.rpc.Stub stub = (javax.xml.rpc.Stub)
(new sas.web.svc.samples.CreditService_Impl().getCreditServiceIFPort());
//Cast the stub to the CreditServiceIF interface to make calls on it.
sas.web.svc.samples.CreditServiceIF cs =
(sas.web.svc.samples.CreditServiceIF)stub;
//Now call the method on the Web service and get the result
double result = cs.getCreditLimit(name, id);
//Write out the result to the JSP
out.println(result + ".</h3>");
}
else
//Either the id or name were blank
out.println("<p><i>Enter a customer name and number.</i></p>");
This is the SAS stored process that is called to determine a customer's credit limit. This simple stored process contains if/else statements that check the customer ID. Depending on your usage scenario and what data you're surfacing through the Web service, your stored process will vary. You can do anything in a stored process that you can do with the SAS System however, with a stored process, you must provide a way to return the results to the user.
%LET outData=work.out; * The name of the dataset to create;
%LET custid=0;
%LET custname="NoUser";
*ProcessBody;
data &outdata;
if &custid = 8675309 then
do;
creditLimit = 2000000;
output;
end;
else if &custid = 1234567 then
do;
creditLimit = 1000000;
output;
end;
else if &custid = 0 then
do;
creditLimit = 0;
output;
end;
else
do;
creditLimit = 5000;
output;
end;
run;
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
This document explains:
To run this sample, you must have the following software installed on your computer:
This samples assumes the installation is on a Windows platform. Modifications of file paths will need to be made when installing on a UNIX platform. This sample was not tested on UNIX, so there is no guarantee this sample will work on a UNIX platform.
The SAS System, Release 8.2 with SAS Integration Technologies. This sample requires that an IOM Bridge server be configured and running on the system where SAS 8.2 is installed. For more information about how to configure an IOM Bridge server, read the SAS Integration Technologies 8.2 Documentation, which describes the setup steps for all the supported platforms.
Tomcat 5.0 for Java WSDP. This is a version of Tomcat 5.0 which will be updated by the Java Web Services Developer Pack 1.5 installer.
Java Web Services Developer Pack 1.5. The Java WSDP contains everything you'll need to build, deploy, and run this sample Web service.
The latest Java Client Development Component. You can download this software from our Web site. This product is included in the SAS Integration Technologies 8.2 Client Components.
Java 2 SDK, Standard Edition (J2SE SDK), version 1.4.2 or J2SE 1.5 JDK. This software can be downloaded from SUN on the J2SE Site.
To use this sample, you should have a working knowledge of Java, Web services, Apache Tomcat, and SAS Integration Technologies.
To install this sample:
Upzip the install of Tomcat 5.0 for Java WSDP to C:\, creating the folder C:\tomcat50-jwsdp. Tomcat 5.0 for JWSDP should be unzipped onto your machine's filesystem prior to installing JWSDP 1.5. During installation of JWSDP 1.5, you will need to point at the location of your Tomcat 5.0 for Java WSDP install. It is important to note that this sample was not tested with the other containers supported by the JWSDP. There is no guarantee this sample will work with the other containers.
Install the Java Web Services Development Pack 1.5. Point at your install of Tomcat 5.0 for JWSDP during the install. After installing the Java WSDP, be sure to follow the installation instructions supplied for your chosen platform, UNIX or Windows. In particular, ensure that the folder C:\tomcat50-jwsdp\apache-ant\bin is added to your path environment variable. If it is not, the ant commands will need to be fully qualified.
Download the sample package to your computer and use the WinZip utility to extract the files to the folder where you installed Tomcat 5.0 for Java WSDP. The default location is C:\tomcat50-jwsdp. Unzipping the package will create the following folders and files inside your Tomcat 5.0 for Java WSDP install folder.
GetCreditLimit.sas - a SAS stored process that can be used to determine a customers credit limit.
Download the 8.2 Java Client Development Component for SAS Integration Technologies from our Web site and unzip it to C:\, creating the folder C:\iomjava.
You might need to edit the build.properties file if you are not able to use the default paths. Edit the file build.properties and update the iomjava property to point to the location where the Java Client Development Component was unzipped. Update the tomcat.root property to specify the location where you unzipped Tomcat 5.0 for JWSDP.
Next you will need to modify the source code in the Web service implementation file, CreditServiceImpl.java.
Locate the following lines:
serverInfo.put("host", "localhost");
serverInfo.put("port", "5307");
serverInfo.put("userName", "username");
serverInfo.put("password", "password");
Modify the host, port, userName, and password properties so this sample will connect to your IOM Bridge server.
Next, locate the line iSP.Repository("file:C:\\tomcat50-jwsdp\\jaxrpc\\samples\\CreditService\\SASRepository");.
If you installed Tomcat 5.0 for JWSDP in a different location, modify the path
accordingly. If you are running against a remote SAS IOM
Bridge server, copy the file GetCreditLimit.sas to the remote
server's file system, and update the path accordingly.
CreditService calls GetCreditLimit.sas to determine a customer's credit limit.
At this point all of the necessary modifications have been made so that the sample Web service and client should build and deploy correctly. The following sequence of commands will build and deploy the Web service. Start up a command prompt (cmd.exe) and change directory to the CreditService folder where build.properties and build.xml are located. Run the following commands:
ant deploy-war
This command will
execute the Ant targets required to build the deployable war
file for both the CreditService and CreditServiceClient
webapps, and deploy them to Tomcat 5.0 for JWSDP. After this command
executes, the Web service should be deployed to your Tomcat server
and should be accessible by a client application. Stop
and Start Tomcat using the links provided with the JWSDP in
the Start menu. Then go to the URL http://localhost:8080/CreditService/CreditService?WSDL
to view the WSDL for CreditService. Simply run ant
deploy-war again if you need to rebuild the sample.
ant run-client
This command runs a console-based client to easily test CreditService. You should see output similar to the following:
run-client: [java] Customer Name: Jenny [java] Customer ID #: 8675309 [java] Getting credit limit....please wait. [java] Credit Limit: 2000000.0
Start up a browser and navigate to URL http://localhost:8080/CreditServiceClient/CreditServiceClient.jsp. This provides an example of calling CreditService from a JSP.
To verify that you can get different credit limits for different customer numbers, you can use these as input:
| Customer Name | Customer ID# | Expected Credit Limit |
|---|---|---|
| Jenny | 8675309 | 2000000.0 |
| Bob | 1234567 | 1000000.0 |
| Everyone Else | Non Zero | 5000.0 |
| Type: | Sample |
| Topic: | Third Party ==> Programming ==> JSP (Java Server Pages) Third Party ==> Programming ==> Java Third Party ==> Output ==> XML |
| Date Modified: | 2008-02-07 07:42:54 |
| Date Created: | 2005-05-03 09:19:06 |
| Product Family | Product | Host | SAS Release | |
| Starting | Ending | |||
| SAS System | SAS Integration Technologies | Microsoft Windows 95/98 | 8.2 TS2M0 | |
| Microsoft Windows 2000 Advanced Server | 8.2 TS2M0 | |||
| Microsoft Windows 2000 Datacenter Server | 8.2 TS2M0 | |||
| Microsoft Windows 2000 Server | 8.2 TS2M0 | |||
| Microsoft Windows NT Workstation | 8.2 TS2M0 | |||
| Microsoft Windows Server 2003 Datacenter Edition | 8.2 TS2M0 | |||
| Microsoft Windows 2000 Professional | 8.2 TS2M0 | |||
| Microsoft Windows Server 2003 Enterprise Edition | 8.2 TS2M0 | |||
| Microsoft Windows Server 2003 Standard Edition | 8.2 TS2M0 | |||
| Microsoft Windows XP Professional | 8.2 TS2M0 | |||
| Windows Millennium Edition (Me) | 8.2 TS2M0 | |||




