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