Introduction
You may have heard the
Latest Brief web service on CodeProject.com. It provides several methods for web client programs to retrieve information about CodeProject.com, such as the latest article updates, the latest comments, and the latest lounge posts, etc. Some very popular articles on the CodeProject site make use of this service. In this article, I am going to present a java client program that uses soap message to call the methods of this web service. My program is not a general java soap client, which means you cannot use it to call other web services directly. However, you can easily modify it for other web services. The program uses only basic Java, it does not depend on any other external class library.
Java Soap Client
So far I have written a lot of web services and published several articles on CodeProject.com. But all of my previous web service related programming were done at a higher level: using ASP.NET or other Microsoft tools to develop the server and the client programs. In fact, I have never cared about how the low level SOAP messages look like, until now. In order to call a web service hosted by IIS such as the LatestBrief service on CodeProject, you need to send soap messages over a http connection. SOAP messages are nothing more than specially formatted XML strings. How the message should be formatted is described in a WSDL (web service description language) file. This link will display the wsdl file for the CodeProject service.
A general SOAP client should be able to read the wsdl file for any web service and figure out how to construct the SOAP messages, all you have to do is supply the parameters for your SOAP call. There are already some general SOAP clients in java available on the internet. But if you already know the format of the SOAP message, you can by-pass the part of analyzing the wsdl file and send a SOAP message directly to the server. This is exactly what my Java program does.
"Stealing" A SOAP Message
But how do I know the exact SOAP message format without analyzing the wsdl file from my code? There are at least two ways. For people with enough knowledge and experience, they can look at the actual wsdl file (by clicking the above link) and figure out what the format is. Unfortunately I am not one of them. Basically, I just "steal" a SOAP message from someone else (I mean another program). Here is what I did. I assume the Microsoft SOAP Toolkit 3.0 is present on the local machine (yes, I am using a Microsoft tool to assist my Java programming, ironic, isn't it?).
- First, click the above link to display the wsdl file in the internet explorer.
- Save it as file latest.wsdl in a folder on your machine.
- Create a virtual web directory named LatestBrief within your default website pointing to this local folder.
- Change the occurrences of the string http://www.codeproject.com/webservices/latest.asmx in the file latest.wsdl to http://localhost/LatestBrief/latest.asp .
- Save the following code as file latest.asp in the same folder.
<%@ LANGUAGE="VBScript" %>
<%
Option Explicit
On Error Resume Next
Dim oReader
Set oReader = CreateObject("MSSOAP.SoapReader30")
oReader.Load Request
Dim oFileSys
Set oFileSys = CreateObject("Scripting.FileSystemObject")
Dim oFile
Set oFile = oFileSys.CreateTextFile("c:\temp\SoapMsg.txt", true, true)
oFile.Write "SoapMsg: " & chr(13) & chr(10) & oReader.DOM.xml & _
chr(13) & chr(10)
oFile.Write "SoapAction: " & chr(13) & chr(10) & _
oReader.soapAction & chr(13) & chr(10)
oFile.Close
Set oFile = Nothing
Set oFileSys = Nothing
Set oReader = Nothing
%>
- Finally, run the following VB script code to call the GetLatestArticleBrief method in the LatestBrief web service on the local machine.
Option Explicit
On Error Resume Next
Dim clt
Set clt = CreateObject("MSSOAP.SoapClient30")
clt.MsSoapInit "http://localhost/LatestBrief/latest.wsdl"
clt.GetLatestArticleBrief 20
Set clt = Nothing
Now, all the information we need to create a java soap client to call the GetLatestArticleBrief method are saved in the file c:\temp\SoapMsg.txt. Before using this information in my java code, let me first explain what is going on here. By creating the latest.wsdl file, the latest.asp file, and the virtual web directory LatestBrief, I essentially hijacked the CodeProject LatestBrief service onto my local machine. The hijacked version does nothing but saving the incoming soap message to a local file. When I run the above VB script to call the GetLatestArticleBrief method, the SOAP message generated by Microsoft SOAP Client 3.0 will be saved into the SoapMsg.txt file. Here is the content of the file.
SoapMsg:
="1.0" ="no"
<SOAP-ENV:Envelope xmlns:SOAPSDK1=<A href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</A>
xmlns:SOAPSDK2=<A href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</A>
xmlns:SOAPSDK3=<A href="http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</A>
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<GetLatestArticleBrief xmlns="http://codeproject.com/webservices/">
<NumArticles
xmlns:SOAPSDK4="http://codeproject.com/webservices/">20
</NumArticles>
</GetLatestArticleBrief>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SoapAction: <A href="http://codeproject.com/webservices/GetLatestArticleBrief">http://codeproject.com/webservices/GetLatestArticleBrief
</A>
In order to call the GetLatestArticleBrief method from java code, I can simply replace the actual parameter value in the above sample message and send it to the CodeProject server.
Similarly, you can steal SOAP sample messages for other methods in the LatestBrief web service and for methods in other web services.
The CodeProjectClient Class
Here is the list of methods and their signatures in the java class I wrote for the LatestBrief service.
import java.io.*;
import java.net.*;
public class CodeProjectClient
{
public static void main( String[] args) throws Exception { ... }
public static String GetLatestArticleBrief(int nNumberOfArticles) { ... }
public static String GetLatestLoungeBrief(int nNumberOfPosts) { ... }
public static String GetLatestCommentsBrief( int nNumberOfMsgs) { ... }
public static String GetNewsflash() { ... }
static HttpURLConnection GetHttpConnection(String sServiceURL,
String sSoapAction)
throws Exception { ... }
static String GetResponseData(HttpURLConnection httpConn)
throws Exception { ... }
}
As you can see from the attached source code, the GetLatestArticleBrief method takes an integer argument which is the number of article updates to be retrieved and returns the XML output string. It first composes the SOAP message using the content of the SoapMsg.txt file listed above, then it opens a http connection to the web service by calling the GetHttpConnection method and sends the SOAP message once the connection is opened. Finally the GetResponseData method is called to get the XML data returned from CodeProject.com. I hope you will agree with me that the implementation is very simple and you can easily modify it to call another web service hosted by IIS once you "stole" sample soap messages for that service. To test the java code, you need to do the following.
- Compile the
CodeProjectClient.java file by executing the command "javac CodeProjectClient.java" or simply use the included CodeProjectClient.class file.
- Run the command "java CodeProjectClient" after setting the correct classpath. The output XML will be printed to the console window.
Disclaimer
I am not an expert on java web programming. This article and the attached source code should only be used for educational and entertainment purposes. Also, I usually approach a problem in a somewhat unconventional way which I do not recommend every other developer to follow. Thanks for reading my article.
Update History
March 28, 2003: Minor text change.