1

I'm trying to connect my iOS-App to an existing Grails backend server. The backend exposes a hessian webservice by using the grails remoting plugin (version 1.3). My Android app successfully calls all webservice methods.

My goal is to transmit a jpeg image from the phone to the server (works with the Android app). My approach is to use create a JSON object with JSONKit and include the image as a base64 encoded string. I'm using HessianKit in an XCode 4 project with ARC targeting iOS 4.2 and Nick Lockwood's NSData+Base64 categories for Base64 encoding (https://github.com/nicklockwood/Base64).

Here's my code:

NSMutableDictionary *jsonPayload = [NSMutableDictionary dictionary];
[jsonPayload setObject:[theImage base64EncodedString] forKey:@"photo"];
NSString* jsonString = [jsonPayload JSONString];

NSURL* url = server_URL;
id<BasicAPI> proxy = (id<BasicAPI>)[CWHessianConnection proxyWithURL:url protocol:@protocol(BasicAPI)];
[proxy addImage:jsonString];  

The problem is that the server throws an expection when called by the app:

threw exception [Hessian skeleton invocation failed; nested exception is com.caucho.hessian.io.HessianProtocolException: addImage__1: expected string at 0x7b ({)] with root cause
Message: addImage__1: expected string at 0x7b ({)
    Line | Method
->> 1695 | error      in com.caucho.hessian.io.HessianInput
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1681 | expect     in     ''
|   1473 | parseChar  in     ''
|    792 | readString in     ''
|    181 | readObject in com.caucho.hessian.io.BasicDeserializer
|   1078 | readObject in com.caucho.hessian.io.HessianInput
|    300 | invoke . . in com.caucho.hessian.server.HessianSkeleton
|    221 | invoke     in     ''
|    886 | runTask .  in java.util.concurrent.ThreadPoolExecutor$Worker
|    908 | run        in     ''
^    680 | run . . .  in java.lang.Thread

All other JSON payloads from my app (Strings, dates, numbers, etc.) can be deserialized by the server without any problem and the other way round, i.e. sending a base64 encoded image as json payload to the app from the server as a response also works.

After spending hours reading bug reports and mailing lists, I suspect that the problem might be that HessianKit only supports the Hessian 1 protocol but the hessian version shipped with remoting 1.3 is 4.0.7. 4.0.7 probably uses the Hessian 2 protocol and isn't compatible backwards. But that's just guessing.

EDIT: Actually, the issue has nothing to do with JSON. The same exception is thrown when I just pass the string as a normal string (and not embedded in JSON) to the webservice.

Has someone experienced a similar problem and knows a solution?

  • I found a workaround that allows me submitting the image but still doesn't explain nor solve the original problem. – Alexander1673437 Sep 17 '12 at 00:28
  • I changed the signature of my webservice to `-(void)addImage:(NSData*)jsonRequest;` and convert the JSON String to NSData before submitting it: `[proxy addImage:[jsonString dataUsingEncoding:NSUTF8StringEncoding];` On the server I simply reverse the conversion `def jsonRequestString = new String(jsonRequest)` That way, Hessian doesn't throw any exceptions and I can decode the image on the server. The downside is that I can't use my existing webservice signatures which accept JSON Strings instead of binary data. – Alexander1673437 Sep 17 '12 at 00:44

0 Answers0