diff --git a/README.md b/README.md index 04c704f..4083e52 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,88 @@ Voila: } ``` +#### Another example + +Note that the method annotated with `@FromJson` does not need to take a String as an argument. Rather it can take +input of any type and Moshi will first parse the JSON to an object of that type and then use the `@FromJson` +method to produce the desired final value. Conversely, the method annotated with `@ToJson` does not have to produce +a String. + +Assume, for example, that we have to parse a JSON in which the date and time of an event are represented as two +separate strings. + +```json +{ + "title": "Blackjack tournament", + "begin_date": "20151010", + "begin_time": "17:04" +} +``` + +We would like to combine these two fields into one string to facilitate the date parsing at a +later point. Also, we would like to have all variable names in CamelCase. Therefore, the `Event` class we +want Moshi to produce like this: + +```java +class Event { + String title; + String beginDateAndTime; +} +``` + +Instead of manually parsing the JSON line per line (which we could also do) we can have Moshi +do the transformation automatically. We simply define another class `EventJson` that directly corresponds to the JSON structure: + +```java +class EventJson { + String title; + String begin_date; + String begin_time; +} +``` + +And another class with the appropriate `@FromJson` and `@ToJson` methods that are telling Moshi how to convert +an `EventJson` to an `Event` and back. Now, whenever we are asking Moshi to parse a JSON to an `Event` it will first parse it to an `EventJson` as an intermediate step. Conversely, to serialize an `Event` Moshi will first +create an `EventJson` object and then serialize that object as usual. + +```java +class EventJsonAdapter { + + @FromJson + Event eventFromJson(EventJson eventJson) { + Event event = new Event(); + event.title = eventJson.title; + event.beginDateAndTime = eventJson.begin_date + " " + eventJson.begin_time; + return event; + } + + @ToJson + EventJson eventToJson(Event event) { + EventJson json = new EventJson(); + json.title = event.title; + json.begin_date = event.beginDateAndTime.substring(0, 8); + json.begin_time = event.beginDateAndTime.substring(9, 14); + return json; + } + +} +``` + +Again we register the adapter with Moshi. + +```java +Moshi moshi = new Moshi.Builder() + .add(new EventJsonAdapter()) + .build(); +``` + +We can now use Moshi to parse the JSON directly to an `Event`. + +```java +JsonAdapter jsonAdapter = moshi.adapter(Event.class); +Event event = jsonAdapter.fromJson(json); +``` + ### Fails Gracefully Automatic databinding almost feels like magic. But unlike the black magic that typically accompanies diff --git a/examples/src/main/java/com/squareup/moshi/recipes/FromJsonWithoutStrings.java b/examples/src/main/java/com/squareup/moshi/recipes/FromJsonWithoutStrings.java new file mode 100644 index 0000000..e2f40f0 --- /dev/null +++ b/examples/src/main/java/com/squareup/moshi/recipes/FromJsonWithoutStrings.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2015 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.squareup.moshi.recipes; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; + +public final class FromJsonWithoutStrings { + + public void run() throws Exception { + // for some reason our JSON has date and time as separate fields - + // we will clean that up during parsing: Moshi will first parse + // the JSON directly to an EventJson and from that the EventJsonAdapter + // will create the actual Event + String json = "" + + "{\n" + + " \"title\": \"Blackjack tournament\",\n" + + " \"begin_date\": \"20151010\",\n" + + " \"begin_time\": \"17:04\"\n" + + "}\n"; + + Moshi moshi = new Moshi.Builder() + .add(new EventJsonAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Event.class); + + Event event = jsonAdapter.fromJson(json); + System.out.println(event); + System.out.println(jsonAdapter.toJson(event)); + } + + public static void main(String[] args) throws Exception { + new FromJsonWithoutStrings().run(); + } + + private static final class EventJson { + String title; + String begin_date; + String begin_time; + } + + public static final class Event { + String title; + String beginDateAndTime; + + @Override + public String toString() { + return "Event{" + + "title='" + title + '\'' + + ", beginDateAndTime='" + beginDateAndTime + '\'' + + '}'; + } + } + + private static final class EventJsonAdapter { + + @FromJson + Event eventFromJson(EventJson eventJson) { + Event event = new Event(); + event.title = eventJson.title; + event.beginDateAndTime = eventJson.begin_date + " " + eventJson.begin_time; + return event; + } + + @ToJson + EventJson eventToJson(Event event) { + EventJson json = new EventJson(); + json.title = event.title; + json.begin_date = event.beginDateAndTime.substring(0, 8); + json.begin_time = event.beginDateAndTime.substring(9, 14); + return json; + } + + } +}