Moshi: How to stop Moshi from parsing a specific object attribute

Created on 31 May 2017  路  11Comments  路  Source: square/moshi

Our JSON can have attributes that are technically JSON objects, but we don't want to parse them - we want to keep them as a JSON-encoded String.

For example:

{
  "method": "capture",
  "category": "data-capture",
  "action": "signup-form",
 "data": {
    "first_name": "Jessica",
    "last_name": "Jones"
  }
}

When parsing this JSON to a Java object named DeviceEvent, we want the data property to be a String - we don't Moshi to parse it to an Object.

Is this possible? If so, how?

Thanks

enhancement

Most helpful comment

I would love to see this feature implemented, my use case being the backend sending GeoJSON data to the client app, and I need to draw that onto a Google Map Fragment which supports GeoJSON. Only problem being I can't maintain the GeoJSON as a string field. Hope this feature gets reviewed!

All 11 comments

This isn鈥檛 supported at the moment. It鈥檚 a thing we should contemplate.

Btw, if you need to do this without real support, you could hack it by deserializing to a map and serializing the map to a string. You would of course lose formatting and such.

final class Foo {
  final String data;
  Foo(String data) {
    this.data = data;
  }

  static final class JsonAdapter {
    private static final class Intermediate {
      final Object data;

      Intermediate(Object data) {
        this.data = data;
      }
    }

    @FromJson Foo fromJson(JsonReader reader,
        com.squareup.moshi.JsonAdapter<Intermediate> intermediateAdapter,
        com.squareup.moshi.JsonAdapter<Object> dataAdapter) throws IOException {
      Intermediate intermediate = intermediateAdapter.fromJson(reader);
      return new Foo(dataAdapter.toJson(intermediate.data));
    }
  }
}

I would love to see this feature implemented, my use case being the backend sending GeoJSON data to the client app, and I need to draw that onto a Google Map Fragment which supports GeoJSON. Only problem being I can't maintain the GeoJSON as a string field. Hope this feature gets reviewed!

+1 would really like to see this implemented as well, are there any updates on ways to work around in the current Moshi version?

Try declaring the unparsed field as an Object. It'll get parsed but it won't be bound to a Java type.

That works perfectly, thank you!

Something that might help anyone else needing to do this, if you have an object with value names that are unknown. You can make it a java.util.Map in your model, and provide a function in your model class like this so that you can get a properly formatted JSON String.

  private Map recipientStatus;

  public String getRecipientStatusJson() {
    return new JSONObject(recipientStatus).toString();
  } 

@derekcsm solution of using Map works fine especially if you want to create another Object from the map.

Would love to see this as well. In my case, I have a complex json sub-object with many nested fields, and I want to save on CPU/allocations by avoiding parsing it at all. I still need the raw json value, however, so I can pass it along to other consumers when I re-serialize my model.

Implementation-wise, it seems this would require a new subclass of JsonReader like JsonValueReader but one that accumulates the raw json instead of parsing or skipping it. It could be called JsonRawReader.

We also need this.
Use case: we are parsing large arrays of flat objects directly out of JsonReader, and some of the fields are arrays of strings or numbers, so we want to save it to db as such.

This is our current approach: reader.readJsonValue().let(adapter::toJson)

Folding into this issues: https://github.com/square/moshi/issues/675

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cdongieux picture cdongieux  路  4Comments

stefanmedack picture stefanmedack  路  4Comments

mleonhard picture mleonhard  路  4Comments

PaulWoitaschek picture PaulWoitaschek  路  4Comments

vpotvin picture vpotvin  路  4Comments