SOAP POC help required

Hi All,

I’ve attached a POC that I’m working on and am getting the following error when trying to do the Operation.invoke step in the getAccountSummary Methods of the AbsoluteRewaredsSvc Stub class:

++Run-Phoney:

    [echo] Running Phoney...

    [java] Reading properties from: D:/opt/Bedrock/Applications/AbsoluteRewardsMobile/Dev/_bedrock_/_build_info_.txt

    [java] Phoney J2ME Simulator v1.4.2.3

    [java] Parameters are Canvas 480x800, Scaled x1, Numpad inverted, File RMS, Sound(on)

    [java] Loaded midlet class com.metismo.j2me.AppMidlet

    [java] FC-PIM Root: C:/ ==> D:/Users/adg/.phoney_fc_pim/c/

    [java] AVI Capture enabled at 25 fps.  Use F2 to start/stop capture.

    [java] Validation Successful!

    [java] 13486

    [java] javax.xml.rpc.JAXRPCException

    [java]    at org.apache.axis.j2me.rpc.Operation.invoke(Unknown Source)

    [java]    at com.metismo.nativedemo.AbsoluteRewardsSvc_PortType_Stub.getAccountSummary(AbsoluteRewardsSvc_PortType_Stub.java:271)

    [java]    at com.metismo.nativedemo.NativeUISOAPThread.run(NativeUISOAPThread.java:52)

BUILD SUCCESSFUL

I’m not sure what to do to debug it to work out what this “Unknown Source” exception is. Any help is much appreciated.

Regards,

Aditya Gollakotay
AbsoluteRewardsMobile.zip (447 KB)

hi
seems like the getAccountSummary operation uses an unsupported java type (patronID is a BigInteger). Have a look in
[url=http://developers.sun.com/mobility/midp/articles/webservices]Oracle Java Technologies | Oracle

for more info.
Best regards
Javier

Thanks Javier,

I’ll update my WSDL to use xsd:int instead of Integer and see if that works

Regards,

Aditya Gollakota

Why not call the webservice from IS, and then wrap this into an IS service that you call from the mobile device?

Hi Dave,

The webservice is to the IS itself, I can do a Http post, but there is already an existing webservice on the IS so am planning on using that one.

I’ve managed to change the inputs and outputs of the webservice to conform to the JSR spec, but still getting the same error at the same point of code.

Attached is the new project.

Regards,

Aditya Gollakota
AbsoluteRewardsMobile.zip (412 KB)

In that case, I’d be tempted to simplify the interface, and rather than calling a webservice from the mobile app, create a rest service and call that. This way, the interface is simplified, and the call will be pretty straight forward.

I don’t believe that you always need to, or necessarily should have to call webservices from your mobile app as it can be sometimes too heavy weight, and a simple REST interface returning XML would be much more straight forward.

Kind regards
Dave

I totally agree. For a mobile application, you just want something lightweight and passing an XML string as inputs and outputs is much easier than anything else.

I’ll try doing this approach and let you know how it goes.

Regards,

Aditya Gollakota

Hi Aditya,

now that not contracted to SOAP any longer, I can offer you a small “Bookstore” app I developed for training.
It displays a Book Catalog, book Details and Rating, and allows users to “Vote” for a book.
The app consumes REST services in IS … a very leightweight IS package without any DB or filesystem access.
All in all (IS package plus Bedrock app) it is zipped in less than 150 KB.

So … let me know if you’re interested. Feedback to the app, of course, welcome!

Regards,
Peter (Corporate University)

Thanks for that Peter.

I managed to get my POC working using http invoke at the moment (client doesn’t have an 8.2 server just yet).

I’ll flip it over to REST when they decide to actually decide to start a project around it.

I have set the service to anonymous, but would like to actually use the username and password provided on the application to authenticate against the IS in the HTTP Headers, but not sure how to do that with the current ServerConnection.connect method.

I decided against using kXML and went with the OOTB SAX parser, which was a little bit easier to work with as you only need to manage the endElement section.

Regards,

Aditya Gollakota

Hi Aditya,

to pass the credentials to IS, I changed the connect method my ServerConnection.java to invoke openHttpConnectionByteArrayData with a 5th argument “request_properties”:

parent.openHttpConnectionByteArrayData (url,
  BRHttpConnectionThread.Encoding_Default, post_data,
  new String[] {"Content-Type", "text/xml", 
    "Authorization", "Basic QWRtaW5pc3RyYXRvcjptYW5hZ2U="});

where “QWRtaW5pc3RyYXRvcjptYW5hZ2U=” is the base64 encoding of “Administrator:manage”.

To encode the credentials dynamically, I found this nice Base64 class that you can easily add as inner class to your NativeUI.java or ServerConnection.java.
Once you did so, you can call

Base64.encode(""+user+":"+password);

Here is the Base64 class to copy-&-paste:

static class Base64 {
 private static final String base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/";
 private static final int splitLinesAt = 76;
 public static byte[] zeroPad(int length, byte[] bytes) {
  byte[] padded = new byte[length]; // initialized to zero by JVM
  System.arraycopy(bytes, 0, padded, 0, bytes.length);
  return padded;
 }
 public static String encode(String string) {
  String encoded = "";
  byte[] stringArray;
  try {
   stringArray = string.getBytes("UTF-8");  // use appropriate encoding string!
  } catch (Exception ignored) {
   stringArray = string.getBytes();  // use locale default rather than croak
  }
  // determine how many padding bytes to add to the output
  int paddingCount = (3 - (stringArray.length % 3)) % 3;
  // add any necessary padding to the input
  stringArray = zeroPad(stringArray.length + paddingCount, stringArray);
  // process 3 bytes at a time, churning out 4 output bytes
  // worry about CRLF insertions later
  for (int i = 0; i < stringArray.length; i += 3) {
   int j = ((stringArray[i] & 0xff) << 16) +
    ((stringArray[i + 1] & 0xff) << 8) + 
    (stringArray[i + 2] & 0xff);
   encoded = encoded + base64code.charAt((j >> 18) & 0x3f) +
    base64code.charAt((j >> 12) & 0x3f) +
    base64code.charAt((j >> 6) & 0x3f) +
    base64code.charAt(j & 0x3f);
  }
  // replace encoded padding nulls with "="
  return splitLines(encoded.substring(0, encoded.length() -
   paddingCount) + "==".substring(0, paddingCount));
 }
 public static String splitLines(String string) {
  String lines = "";
  for (int i = 0; i < string.length(); i += splitLinesAt) {
   lines += string.substring(i, Math.min(string.length(), i + splitLinesAt));
   lines += "\r\n";
  }
  return lines;
 }
}

Hope this helps.

Regards,
Peter

I forgot to mention the reference for the Base64 class:
http://www.wikihow.com/Encode-a-String-to-Base64-With-Java

Regards,
Peter