Return raw JSON string from lookupIn()

I’ve exhausted google and this forum and I can’t find a way to accomplish something that used to be possible in the 2.x versions of the Java SDK. I want to use lookupIn to get sub docs out of a larger JSON document, but I want the result back in a plain jane JSON string.

This is for the CFCouchbase SDK which is written in CFML and wraps the Java SDK. CFML has its own JSON serializers and deserializers which deal in native datatypes to the language. The trick is I need something

  • generic (This is an SDK for CF developers which can be used in any way imaginable)
  • that will work for any data type that may be coming back (array, object, string, boolean, etc)
  • and I don’t know what the value is ahead of time

This rules out using the contentAsObject() and contentAsArray() methods since I don’t know what random values the user may be targeting with their path. I can’t use contentAs( index, class ) as well since I don’t know the type of data.

For all other get() kv operations, I use the RawStringTranscoder as my default transcoder, which allows me to handle the JSON deserialization myself. But the LookupInOptions do not accept a transcoder. It only allows me to set a JsonSerializer which does not help me since I don’t want the Java SDK doing any sort of deserialization on the JSON!.

How can I get back a raw JSON string from the lookupIn() method for any path without knowing ahead of type what type of data is coming back?

1 Like

Hi Brad,

Sorry for the frustration this caused you. Does this code do what you want?

byte[] jsonBytes = lookupInResult.contentAs(index, byte[].class);
String jsonString = new String(jsonBytes, StandardCharsets.UTF_8);

This gives you the JSON representation of the field, regardless of its actual type, with zero transcoding by the SDK.

If you have an idea for a friendlier way to expose this behavior, we should discuss adding it to a future version of the SDK.

Thanks,
David

I’m using this really ugly workaround until I can find a better way:

try {
 var JSONString = lookupInResult.contentAsObject( i ).toString();
} catch( any e ) {
  try {
    var JSONString = lookupInResult.contentAsArray( i ).toString();
  } catch (any e2) {
    var JSONString = lookupInResult.contentAs( i, createObject("java", "java.lang.Object").getClass() );
  }
}

Thanks for the quick reply. I’ll give this a try and see if it works.

Excellent-- this approach appear to be working well. My final CFML code looks similar to this:

var JSONString = toString( lookupInResult.contentAs( i, javaCast( 'byte[]', [] ).getClass() ), 'utf-8' );

Thanks again for your quick and helpful response. With this, I now have 253 passing unit tests for the CFCouchbase SDK running on the latest Java client :slight_smile:

So this is an interesting question. Where the other kv operations allow me to set a transcoder, the lookupIn() method only allows me to customise the JSON serializer, which of course doesn’t make sense if I don’t want the JSON deserialized at all. Perhaps it would be best to simply add another method to the lookupInResult such as

String rawJSON = lookupInResult.getContentAsRawJSON();
1 Like