Connecting to a webservice from an ADF application using JDeveloper 10.1.2

In the Netherlands, the addresses of houses are uniquely defined by their postal code and house number (is this correct English?). One of our customers wanted to have the street and city automagically determined by the house number and postal code using a webservice. This webservice is provided by www.webservices.nl so it was up to me to make our application use that webservices. One of the challenges I had was to make the webservice be contacted via HTTPS. I got a X509CertChainIncompleteErr while trying so read on to learn how I solved this.

Please note that the webservice of webservices.nl used in this example is a paid service. If you like to follow my steps, please use a free service instead of this one.

First things first: creating a webservice stub. This can easily be done with JDeveloper 10.1.2 using the WSDL of the webservice. The WDSL of this particular webservice of www.webservices.nl can be accessed  via https://ws1.webservices.nl/postcode/soapnoheaders?wsdl and the documentation for this webservice at https://ws1.webservices.nl/postcode/soapnoheaders. So, I downloaded it to my hard disk, opened my application workspace in JDeveloper and right clicked the Model project which was already set up for ADF Business Components.

Connecting to a webservice from an ADF application using JDeveloper 10.1.2 CreateWebserviceStub1

Next I selected the WDSL file from my hard disk. Also I told the wizard to generate a main method so I could test the webservice client stand alone, before incorporating it into the rest of the application.

Connecting to a webservice from an ADF application using JDeveloper 10.1.2 CreateWebserviceStub2

The final step is to select the methods you need in the stub. In my case I only needed the reactAddressReeksPostcodeSearch method which uses a session id and a string in the form postcode + number (e.g. 3439MN15 which are the postal code and number for AMIS) to fetch lots of data about that address, including the street and city. In order to get the session id you need to login (like I said, this is a paid service) and logout afterwards. So, I only need three methods and not the rest.

Connecting to a webservice from an ADF application using JDeveloper 10.1.2 CreateWebserviceStub3

In the newly created webservice stub I created a simple method that calls the login, reactAddressReeksPostcodeSearch and logout methods sequentially. It looks like this

public String[] getStreetAndCity(String postcodenr) 
{
    PCReeks pcReeks = null;
    String[] result = new String[2];
    try {
      String reactId = login(mylogin, mypass);
      pcReeks = reactAddressReeksPostcodeSearch(reactId, postcodenr);
      result[0] = pcReeks.getStraatnaam();
      result[1] = pcReeks.getPlaatsnaam();
      reactLogout(reactId);
    } catch(Exception e) 
    {
      e.printStackTrace();
      throw new JboException("An error occured while getting the street and city.");
    }
    return result;
}

Here, mylogin and mypass are the loginname and password as provided by webservices.nl. When I made the main method of this class call the getStreetAndCity method with a valid string (I used  3439MN15 which are the postal code and number for AMIS) I got an X509CertChainIncompleteErr error. First I searched the webservices.nl online documentation and found this page, explaining how to make the webservices.nl SSL certificates known to my JVM. The JVM JDeveloper uses is located in <jdev install>\jdk\jre and the cacerts keystore is in <jdev install>\jdk\jre\lib\security. Running the keytool.exe command from that directory nicely added the SSL certificates to the cacert keystore in that directory. Using

..\..\bin\keytool.exe -keystore cacerts -list

showed the two keys to have been installed in the keystore. Unfortunately, this didn’t solve the problem. Searching the JDeveloper forums, I found this solution. Making the stub use the Apache SOAPHttpConnection instead of the OracleSOAPHttpConnection and commenting out the setTransportProperties and getTransportProperties fixed the issue Smiley

So, next I created a method on my ApplicationModule and published it on the client interface:

public String[] getStreetAndCity(String postcodenr)
{
  postcodenr = postcodenr.replaceAll(" ", "");
  WebservicesNlStub stub = new WebservicesNlStub();
  String[] result = stub.getStreetAndCity(postcodenr);
  return result;
}

The postcodenr.replaceAll(” “,””) is there to get rid of all spaces in the String. This is the way the webservice needs it, though I could have put this line of code in the webservice stub class itself. Finally, I modified my DataAction class (which extends JhsDataAction by the way, we are JHeadStart users here) to call this method everytime a new row is entered. I put this piece of code into the onCommit method

HttpServletRequest request = daContext.getHttpServletRequest();
String postcode = (String)request.getParameter("Postcode");
String huisnummer = (String)request.getParameter("Huisnummer");
AppModule app = getAppModule(daContext);
String[] result = app.getStreetAndCity(postcode + huisnummer);
DCIteratorBinding myIterBinding = daContext.getBindingContainer().findIteratorBinding("MyIterator");
Row row = myIterBinding.getCurrentRow();
row.setAttribute("Adres", result[0]);
row.setAttribute("Woonplaats", result[1]);

So now, everytime a postal code and number are entered in our form, the street and city are looked up when the form is submitted.

One Response

  1. Catherine Adams September 12, 2011