Monday, September 7, 2009

60 seconds on SOAP-based Web Services

According to this book, there are 74 distinct initiatives trying to define what a Web Service should look like. And I bet, there are at least 74 different abbreviations around to describe different parts of it. So it's surprising how simple it is to create a Web Service with JDK 1.6. First you define an interface with a bunch of annotations:

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
// use RPC or 'wrapped' document-style
@SOAPBinding(style = Style.RPC)
//@SOAPBinding(style = Style.DOCUMENT,
// parameterStyle = SOAPBinding.ParameterStyle.WRAPPED )
public interface Example
{
 @WebMethod public String getGreeting( @WebParam(name="myname") String myname);
}
And then implement the service itself. Use a thread-pool if your application is multi-threaded.

import javax.jws.WebService;
import javax.xml.ws.Endpoint;

@WebService(endpointInterface = "simple.Example")
public class ExampleImpl implements Example
{
 @Override
 public String getGreeting(String myname)
 {
   return "hello, " + myname;
 }

 public static void main(String[] args)
 {
   String url = "http://127.0.0.1:9876/example";
   System.out.println("Starting WebService at: " + url);
   System.out.println("WSDL available at:      " + url + "?wsdl");

   Endpoint endpoint = Endpoint.create(new ExampleImpl());
   //endpoint.setExecutor( Executors.newFixedThreadPool(10) );
   endpoint.publish(url);
 }
}
The resulting WSDL definition of this service can be looked at http://127.0.0.1:9876/example?wsdl (use Firefox or IE, not Chrome!). Any SOAP-based client (such as the XML Test Utility in General Interface, see previous post) can now invoke this service.
REST-style would be harder to implement, but easier to test. In the REST case, you can simply do: http://127.0.0.1:9876/rs?name="Pete" for invocations. The difference to the previous solution is that with REST-style, the client uses an HTTP GET to invoke a method and the return value can be any kind of XML, not just a SOAP envelope.
The code above implements the main 'standard', but its also the most bloated possibilty. More efficient, but less standardized, is a message encoding of JSON instead of XML, or better, use the Google Web Toolkit. If you are in full control of the server and the client and don't need to follow standards, GWT seems an excellent choice right now.

Friday, September 4, 2009

General Interface Primer

There's now an open-source Ajax GUI builder called General Interface which looks quite promising. A bunch of components that are somewhat familiar to Swing developers. Of course, all logic is Javascript :-(
After installation, here some tips that could come in handy:
  1. Look at the video tutorials, the best one for tables(matrix) isn't actually on that page, but here.
  2. Defining Javascript functions doesn't always work, even after Save/Reload. Try to restart and reload the page before giving up.
  3. You might sneeze at the package names, but trust me, in Javascript conflicts are easy to create. Here's a simple example on a function called jmsw.doAction(index) :
    
    // name of the package to create: jmsw
    jsx3.lang.Package.definePackage(  "jmsw", function(jmsw) {
     jmsw.doAction = function(index) // define doAction(index)
     {
       ...
     };
    });
    
  4. Do Control+Click on a component (such as a button) to locate its definition in the 'Component Hierachy'.
  5. Float a Palette to get more space or to move it to the bottom panel: Upper Right Corner of a Palette View, click on 'Floating'. Use Menu->Palettes to enable/disable a palette.
  6. The 'XML Mapping Tool' always starts with the same default of ..Address.wsdl, but this will not be the one you will be working with. To change the default of this initial URI, edit C:\TIBCO\gi-3.8-max\GI_Builder\plugins\jsx3.ide.mapping\components\Inputs\wsdl.xml and search for 'Address, comment it out and add your own WebService URI:
    
           <!-- use different default for XML Mapping Tool:
           <strings jsxname="jsx_schema_wsdlurl" jsxvalue="jsxplugin://jsx3.ide.mapping/samples/Address.wsdl" jsxwidth="100%"/>
           -->
    
           <strings jsxname="jsx_schema_wsdlurl" jsxvalue="http://127.0.0.1:9876/rs?wsdl" jsxwidth="100%"/>