原文地址:http://www.studytrails.com/java/json/java-google-json-type-adapter.jsp
Using Custom Type Adapter
在之前的教程中我們已經見到如何序列化和反序列化有繼承或者沒有繼承關係的Java類.Gson默認使用內省來序列化和反序列化.但是,有些時候,我們需要自定義的轉換策略來取代默認的轉換策略.所謂的轉換策略就是控制如何將一個java對象轉換成json字符串以及json字符串轉換成java對象.Gson提供了指定轉換策略的方法.
讓我們看看如何去實現轉換策略:
首先寫一個繼承TypeAdapter的類,然後實現 public abstract T read(JsonReader in) throws IOException;和public abstract void write(JsonWriter out, T value) throws IOException;方法.這個Adapter記得處理null哦.通過GsonBuilder來註冊這個自定義的Adapter.看demo:
package com.studytrails.json.gson;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class DatasetTypeAdapterExample8 {
public static void main(String[] args) throws MalformedURLException, IOException {
String url = "http://freemusicarchive.org/api/get/albums.json?api_key=60BLHNQCAOUFPIBZ&limit=5";
String json = IOUtils.toString(new URL(url));
// Create the custom type adapter and register it with the GsonBuilder
// class.
Gson gson = new GsonBuilder().registerTypeAdapter(Dataset.class, new DatasetTypeAdapter()).create();
// deserialize the json to Albums class. The Dataset objects are part of
// the Albums class. Whenever Gson encounters an object of type DataSet
// it calls the DatasetTypeAdapter to read and write json.
Albums albums = gson.fromJson(json, Albums.class);
System.out.println(albums.getDataset()[1].getAlbum_title());
// prints
// http://freemusicarchive.org/music/The_Yes_Sirs/Through_The_Cracks_Mix_Vol_1/
}
}
自定義的Adapter
{
@Override
public Dataset read(JsonReader reader) throws IOException {
// the first token is the start object
JsonToken token = reader.peek();
Dataset dataset = new Dataset();
if (token.equals(JsonToken.BEGIN_OBJECT)) {
reader.beginObject();
while (!reader.peek().equals(JsonToken.END_OBJECT)) {
if (reader.peek().equals(JsonToken.NAME)) {
if (reader.nextName().equals("album_url"))
dataset.setAlbum_title(reader.nextString());
else
reader.skipValue();
}
}
reader.endObject();
}
return dataset;
}
@Override
public void write(JsonWriter out, Dataset value) throws IOException {
}
}" data-snippet-id="ext.83bafcd0d53693692abaee0e64d8e020" data-snippet-saved="false" data-csrftoken="aHaDPxOI-pwTU5daPAiWAaqZS1cywPKdvIQQ" data-codota-status="done">package com.studytrails.json.gson;
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
/**
* The Dataset class contains the information about a particular Album.
* album_title and album_url are two distinct fields in the json. The Dataset
* object contains the field album_title. Normally Gson would map the
* album_title property in the json the the album_title field in the Dataset
* object. However, we dont want that. We want to use the album_url property
* from the json object to populate the album_title field in the Dataset object.
* we build a custom TypeAdapter to do that. This is just a trivial case, you
* could also combine album_url and album_title properties and set it to the
* album_title field of the Dataset Object.
*
*/
public class DatasetTypeAdapter extends TypeAdapter<Dataset> {
@Override
public Dataset read(JsonReader reader) throws IOException {
// the first token is the start object
JsonToken token = reader.peek();
Dataset dataset = new Dataset();
if (token.equals(JsonToken.BEGIN_OBJECT)) {
reader.beginObject();
while (!reader.peek().equals(JsonToken.END_OBJECT)) {
if (reader.peek().equals(JsonToken.NAME)) {
if (reader.nextName().equals("album_url"))
dataset.setAlbum_title(reader.nextString());
else
reader.skipValue();
}
}
reader.endObject();
}
return dataset;
}
@Override
public void write(JsonWriter out, Dataset value) throws IOException {
}
}
Albums類
package com.studytrails.json.gson;
public class Albums {
private String title;
private Dataset[] dataset;
public void setTitle(String title) {
this.title = title;
}
public void setDataset(Dataset[] dataset) {
this.dataset = dataset;
}
public String getTitle() {
return title;
}
public Dataset[] getDataset() {
return dataset;
}
}
Dataset類
otherProperties = new HashMap();
public String getAlbum_id() {
return album_id;
}
public void setAlbum_id(String album_id) {
this.album_id = album_id;
}
public String getAlbum_title() {
return album_title;
}
public void setAlbum_title(String album_title) {
this.album_title = album_title;
}
public Object get(String name) {
return otherProperties.get(name);
}
}" data-snippet-id="ext.3b5cbafc07313a31661f7f1e95c5f65e" data-snippet-saved="false" data-csrftoken="9egCWouf-Zn6Dhwicbd3bwBZDTyrWqMu3Zlw" data-codota-status="done">package com.studytrails.json.gson;
import java.util.HashMap;
import java.util.Map;
public class Dataset {
private String album_id;
private String album_title;
private Map<String , Object> otherProperties = new HashMap<String , Object>();
public String getAlbum_id() {
return album_id;
}
public void setAlbum_id(String album_id) {
this.album_id = album_id;
}
public String getAlbum_title() {
return album_title;
}
public void setAlbum_title(String album_title) {
this.album_title = album_title;
}
public Object get(String name) {
return otherProperties.get(name);
}
}