Add example for custom JsonAdapter.

This commit is contained in:
David Mihola
2015-10-06 17:06:05 +02:00
committed by jwilson
parent 6ed45f0bb2
commit 68f2fb1d74
2 changed files with 172 additions and 0 deletions

View File

@@ -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<Event> jsonAdapter = moshi.adapter(Event.class);
Event event = jsonAdapter.fromJson(json);
```
### Fails Gracefully ### Fails Gracefully
Automatic databinding almost feels like magic. But unlike the black magic that typically accompanies Automatic databinding almost feels like magic. But unlike the black magic that typically accompanies

View File

@@ -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<Event> 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;
}
}
}