Is there a way to in-line JSON

1,536 views
Skip to first unread message

Peter Lin

unread,
Sep 25, 2012, 5:22:20 PM9/25/12
to googl...@googlegroups.com
This may be a crazy question, but here goes.

I have a java object, which has a property that contains JSON from a third party. Using the default gson.toJson() method it wraps the value in double quotes.

I would like gson to in-line the value associated with the object property without the quotes. For example:

default gson generated output

("object1":{"property1":"1","property2":"2","property3":"3"},"jsonAttachment":"{"name":"first","email":"m...@domain.com"}" }

I would like the output to inline the jsonAttachment so it looks like this.

("object1":{"property1":"1","property2":"2","property3":"3"},"jsonAttachment":{"name":"first","email":"m...@domain.com"} }

I tried writing a custom TypeAdapter and TypeAdapterFactory, but it looks like neither of those can in-line arbitrary JSON blob. I looked at JsonWriter to see if I could modify it to in-line the value of jsonAttachment property. Before I try that, has anyone else tried to in-line JSON with gson?  If so, what did you do to make gson in-line arbitrary json text blob.

thanks

peter

Inderjeet Singh

unread,
Sep 25, 2012, 6:10:34 PM9/25/12
to googl...@googlegroups.com
You should be able to use a TypeAdapter or JsonSerializer/JsonDeserializer to do this. Seems fairly straightforward.

Inder

Adrian Cole

unread,
Sep 25, 2012, 9:35:57 PM9/25/12
to googl...@googlegroups.com

You can use a custom type for the json literal. For example, we have this type adapter which handles the serialization concerns:

https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/json/internal/NullHackJsonLiteralAdapter.java

Then we defined a wrapper type for json literals named JsonBall and registered the above type adapter:

public static class NullHackJsonBallAdapter extends NullHackJsonLiteralAdapter<JsonBall> {

@Override protected JsonBall createJsonLiteralFromRawJson(String json) { return new JsonBall(json); }

}

Unit tests etc which show this:

https://github.com/jclouds/jclouds/blob/master/core/src/test/java/org/jclouds/json/internal/NullHackJsonLiteralAdapterTest.java

Hope this helps!
-A

--
You received this message because you are subscribed to the Google Groups "google-gson" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-gson/-/huTzAAOwatYJ.
To post to this group, send email to googl...@googlegroups.com.
To unsubscribe from this group, send email to google-gson...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-gson?hl=en.

Maaartin

unread,
Sep 25, 2012, 10:18:52 PM9/25/12
to googl...@googlegroups.com
On Wednesday, September 26, 2012 12:10:34 AM UTC+2, Inderjeet Singh wrote:
You should be able to use a TypeAdapter or JsonSerializer/JsonDeserializer to do this. Seems fairly straightforward.

I thought so, a trivial TypeAdapter, I just wrote `out.beginObject()`, ... and then I recognized that there's nothing allowing me to output a string without quotes. Or is it?

Peter Lin

unread,
Sep 25, 2012, 10:33:58 PM9/25/12
to googl...@googlegroups.com

I did try custom TypeAdapter, but it escapes the quotes and it wraps the whole value in quotes.

Peter Lin

unread,
Sep 25, 2012, 10:39:24 PM9/25/12
to googl...@googlegroups.com

thanks I will give that a try.

Adrian Cole

unread,
Sep 25, 2012, 10:57:11 PM9/25/12
to googl...@googlegroups.com
Yeah, it is a little, well very hacky to do this.

Create a type adapter, and inside the write method
1. swap the field JsonWriter.out to a Writer that looks for "null"
and replaces with your text instead
2. With the hacked JsonWriter in hand, endure serializeNulls is set,
then invoke jsonWriter.nullValue() to set your value
3. undo above in a finally block

ends up like this:

Writer writer = getWriter(jsonWriter);
boolean serializeNulls = jsonWriter.getSerializeNulls();
try {
// we are using an implementation hack which depends on
replacing null with the raw json
// supplied as a parameter. In this case, we must ensure we
indeed serialize nulls.
NullReplacingWriter nullReplacingWriter = new
NullReplacingWriter(writer, toString(value));
setWriter(jsonWriter, nullReplacingWriter);
jsonWriter.setSerializeNulls(true);
jsonWriter.nullValue();
} finally {
setWriter(jsonWriter, writer);
jsonWriter.setSerializeNulls(serializeNulls);
}

fun?

-A
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/ex1genJiTeoJ.

Peter Lin

unread,
Sep 25, 2012, 11:08:53 PM9/25/12
to googl...@googlegroups.com

I was thinking of doing something similar to that and felt it was a bit hacky.

I wanted to avoid an ugly hack to inline arbitrary JSON.

Peter Lin

unread,
Sep 26, 2012, 10:18:05 AM9/26/12
to googl...@googlegroups.com

the other idea I had that was "less hacky" was to extend JsonWriter directly by adding a new method and then use it from a custom TypeAdapterFactory

since JsonWriter.value(String) currently does this.

  public JsonWriter value(String value) throws IOException {
    if (value == null) {
      return nullValue();
    }
    writeDeferredName();
    beforeValue(false);
    string(value);
    return this;
  }

I could skip the string(value) call, which escapes the quotes. In "theory" that would be less hacky, but it would mean forking Gson, which doesn't sound appealing to me.



On Tuesday, September 25, 2012 10:57:12 PM UTC-4, Adrian Cole wrote:

Peter Lin

unread,
Oct 12, 2012, 8:31:33 AM10/12/12
to googl...@googlegroups.com

Here is a follow up on inlining arbitrary JSON. I thought other people might find the details useful.

Instead of using serializeNulls, I enhanced JsonWriter with an additional method.

  /**
   * Writes {@code value} without quotes and inlines the
   * text as a JSON text blob.
   * @param value
   * @return
   * @throws IOException
   */
  public JsonWriter inLineValue(String value) throws IOException {

      if (value == null) {
          return nullValue();
      }
      writeDeferredName();
      out.write(value);
      return this;
  }


Next, I write a custom TypeAdapter that uses the method like this.

public class MyObjectAdapter extends TypeAdapter<MyObject> {

    @Override
    public MyObject read(JsonReader reader) throws IOException {
        return null;
    }

    @Override
    public void write(JsonWriter writer, MyObject source) throws IOException {
        if (source == null) {
            writer.nullValue();
            return;
        } else {
            writer.beginObject();
           
            writer.name("status");
            writer.beginObject();
            writer.name("severity");
            writer.value(source.getStatusInformation().getSeverity());
            writer.name("message");
            writer.value(source.getStatusInformation().getMessage());
            writer.endObject();
           
            // write parse hint
            if (source.getJSONBlob() != null) {
                writer.name("jsonblob");
                writer.beginObject();
                writer.inLineValue(source.getJSONBlob());
                writer.endObject();
            }

            writer.endObject();
        }
    }

}

I don't know if the additional method is useful to other people, but it is one way of inlining arbitrary JSON blobs without resorting to ugly hacks.




On Tuesday, September 25, 2012 10:57:12 PM UTC-4, Adrian Cole wrote:

Adrian Cole

unread,
Oct 12, 2012, 5:17:30 PM10/12/12
to googl...@googlegroups.com

Indeed! Particularly where patching a class in gson namespace isn't classified as 'ugly hack' :)

-A

To view this discussion on the web visit https://groups.google.com/d/msg/google-gson/-/BEfD6kpBFBYJ.

Peter Lin

unread,
Oct 15, 2012, 11:14:32 AM10/15/12
to googl...@googlegroups.com

funny thing is, last week I checked the open tickets on Gson and saw someone else requested the same kind of feature, so I updated the ticket with example of what I did.

Agree that patching gson is also a hack, but atleast it's in a ticket now. hopefully they will consider including it, so that it won't be a "hack".

Adrian Cole

unread,
Oct 15, 2012, 12:03:08 PM10/15/12
to googl...@googlegroups.com

Amen to that!

To view this discussion on the web visit https://groups.google.com/d/msg/google-gson/-/Q62O2kK36VoJ.
Reply all
Reply to author
Forward
0 new messages