欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Gson中@JsonAdater注解的幾種方式總結(jié)

 更新時(shí)間:2022年08月30日 10:31:19   作者:ydfind  
這篇文章主要介紹了Gson中@JsonAdater注解的幾種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Gson @JsonAdater注解的幾種方式

總結(jié)

可以通過自定義TypeAdapter和TypeAdapterFactory的方式,自定義gson的序列化和反序列規(guī)則,TypeAdapterFactory可以拿到上下文gson、TokenType類型;

也可以通過繼承JsonReader重新寫一次代碼,在beginArray和endArray想辦法跳過array的string形式的左右 雙引號(hào)", gson.fromJson(myJsonReader, Type)也可以實(shí)現(xiàn) 解析時(shí)自動(dòng)將String變?yōu)長(zhǎng)ist,但采用注解@JsonAdapter的方式更為正規(guī)一些;

問題描述

json字符串:

{
? ? "cityIds": "[1,2,1001,13131]",
? ? "types": "[{\"name\": \"biz\",\"details\": [1]}]"
}

java對(duì)象定義:

?@Data
? ? public static class RequestParams {
? ? ? ?// json字符串里對(duì)應(yīng)的是String
? ? ? ? private List<TypeItem> types;
? ? ? ? private List<Integer> cityIds;
? ? }
? ? @Data
? ? public static class TypeItem {
? ? ? ? private String name;
? ? ? ? private List<Integer> details;
? ? }

可以看到j(luò)son里面cityIds和types都是String,而pojo里則是List,使用gson的fromJson將json轉(zhuǎn)為pojo會(huì)發(fā)生報(bào)錯(cuò)

方式一

? @JsonAdapter(StringCollectionTypeAdapterFactory.class)
? ? ?private List<TagItem> tags;
? ? ?@JsonAdapter(StringCollectionTypeAdapterFactory.class)
? ? ?private List<Integer> cityIds;
public static class StringCollectionTypeAdapterFactory implements TypeAdapterFactory {
? ? ? ? @Override
? ? ? ? public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
? ? ? ? ? ? // 為了write的時(shí)候能使用到elementTypeAdapter
? ? ? ? ? ? Type type = typeToken.getType();
? ? ? ? ? ? Class<? super T> rawType = typeToken.getRawType();
? ? ? ? ? ? if (!Collection.class.isAssignableFrom(rawType)) {
? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? }
? ? ? ? ? ? Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
? ? ? ? ? ? TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
? ? ? ? ? ??
? ? ? ? ? ? TypeAdapter<T> result = new Adapter(gson, elementTypeAdapter, typeToken);
? ? ? ? ? ? return result;
? ? ? ? }
? ? ? ? private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
? ? ? ? ? ? private final TypeAdapter<E> elementTypeAdapter;
? ? ? ? ? ? private final Gson gson;
? ? ? ? ? ? private final TypeToken listType;
? ? ? ? ? ? public Adapter(Gson context, TypeAdapter<E> elementTypeAdapter, TypeToken listType) {
? ? ? ? ? ? ? ? this.elementTypeAdapter = elementTypeAdapter;
? ? ? ? ? ? ? ? this.gson = context;
? ? ? ? ? ? ? ? this.listType = listType;
? ? ? ? ? ? }
? ? ? ? ? ? @Override public Collection<E> read(JsonReader in) throws IOException {
? ? ? ? ? ? ? ? if (in.peek() == JsonToken.NULL) {
? ? ? ? ? ? ? ? ? ? in.nextNull();
? ? ? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? List<E> list = gson.fromJson(in.nextString(), listType.getType());
? ? ? ? ? ? ? ? return list;
? ? ? ? ? ? }
?
? ? ? ? ? ? // write后可以將array的string格式,重新變成array
? ? ? ? ? ? @Override public void write(JsonWriter out, Collection<E> collection) throws IOException {
? ? ? ? ? ? ? ? if (collection == null) {
? ? ? ? ? ? ? ? ? ? out.nullValue();
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? out.beginArray();
? ? ? ? ? ? ? ? for (E element : collection) {
? ? ? ? ? ? ? ? ? ? elementTypeAdapter.write(out, element);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? out.endArray();
? ? ? ? ? ? }
? ? ? ? }
? ? }

方式二-write原樣

public static class StringCollectionTypeAdapterFactory1 implements TypeAdapterFactory {
? ? ? ? @Override
? ? ? ? public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
? ? ? ? ? ? return new Adapter(gson, typeToken);
? ? ? ? }
? ? ? ? private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
? ? ? ? ? ? private final Gson gson;
? ? ? ? ? ? private final TypeToken listType;
? ? ? ? ? ? public Adapter(Gson context, TypeToken listType) {
? ? ? ? ? ? ? ? this.gson = context;
? ? ? ? ? ? ? ? this.listType = listType;
? ? ? ? ? ? }
? ? ? ? ? ? @Override public Collection<E> read(JsonReader in) throws IOException {
? ? ? ? ? ? ? ? if (in.peek() == JsonToken.NULL) {
? ? ? ? ? ? ? ? ? ? in.nextNull();
? ? ? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? List<E> list = gson.fromJson(in.nextString(), listType.getType());
? ? ? ? ? ? ? ? return list;
? ? ? ? ? ? }
? ? ? ? ? ? @Override public void write(JsonWriter out, Collection<E> collection) throws IOException {
? ? ? ? ? ? ? ? if (collection == null) {
? ? ? ? ? ? ? ? ? ? out.nullValue();
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? out.value(gson.toJson(collection));
? ? ? ? ? ? }
? ? ? ? }
? ? }

方式三-簡(jiǎn)單寫法

private static class CollectionStringTypeAdapterFactory implements TypeAdapterFactory {
? ? ? ? @Override
? ? ? ? public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
? ? ? ? ? ? return new TypeAdapter<T>() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void write(JsonWriter out, T value) throws IOException {
? ? ? ? ? ? ? ? ? ? if (value == null) {
? ? ? ? ? ? ? ? ? ? ? ? out.nullValue();
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? gson.getAdapter(type).write(out, value);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public T read(JsonReader in) throws IOException {
? ? ? ? ? ? ? ? ? ? if (in.peek() == JsonToken.NULL) {
? ? ? ? ? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (in.peek() == JsonToken.BEGIN_ARRAY) {
? ? ? ? ? ? ? ? ? ? ? ? return gson.getAdapter(type).read(in);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? T collection = gson.fromJson(in.nextString(), type.getType());
? ? ? ? ? ? ? ? ? ? return collection;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? }
? ? }

測(cè)試用例如下所示:

@Test
? ? public void testGson1() {
? ? ? ? Gson gson = new Gson();
? ? ? ? RequestParams requestParam;
? ? ? ? String json;
? ? ? ? // 1.自動(dòng)將string轉(zhuǎn)為屬性的List
? ? ? ? json = "{\"id\": \"000000\",\"types\": \"[{\\\"name\\\":\\\"name1\\\",\\\"list\\\":[1,2]},{\\\"name\\\":\\\"name2\\\",\\\"list\\\":[3,4]}]\",\"keywordIds\": \"[12,13]\"}";
? ? ? ? System.out.println(json);
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? ? ? // 2.jsonArray也可以轉(zhuǎn)為L(zhǎng)ist
? ? ? ? json = "{\"id\": \"000000\",\"keywordIds\": [12,13],\"types\": [{\"name\":\"name1\",\"list\":[1,2]},{\"name\":\"name2\",\"list\":[3,4]}]}";
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? ? ? // 3.換行的方式呢
? ? ? ? json = "{\n" +
? ? ? ? ? ? ? ? "\t\"id\": \"000000\",\n" +
? ? ? ? ? ? ? ? "\t\"keywordIds\": [12,13],\n" +
? ? ? ? ? ? ? ? "\t\"types\": [{\"name\":\"name1\",\"list\":[1,2]},{\"name\":\"name2\",\"list\":[3,4]}]\n" +
? ? ? ? ? ? ? ? "}";
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? ? ? // 4.能否將List里面的Integer變成String呢
? ? ? ? json = "{\n" +
? ? ? ? ? ? ? ? "\t\"id\": \"000000\",\n" +
? ? ? ? ? ? ? ? "\t\"keywordIds\": [12,13],\n" +
? ? ? ? ? ? ? ? "\t\"types\": [{\"name\":\"name1\",\"list1\":[1,2]},{\"name\":\"name2\",\"list1\":[3,4]}]\n" +
? ? ? ? ? ? ? ? "}";
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? ? ? // 5.能否將List里面的Integer變成String
? ? ? ? json = "{\n" +
? ? ? ? ? ? ? ? "\t\"id\": \"000000\",\n" +
? ? ? ? ? ? ? ? "\t\"keywordIds1\": [12,13],\n" +
? ? ? ? ? ? ? ? "\t\"types\": [{\"name\":\"name1\",\"list1\":[1,2]},{\"name\":\"name2\",\"list1\":[3,4]}]\n" +
? ? ? ? ? ? ? ? "}";
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? ? ? // 6.自動(dòng)將string轉(zhuǎn)為屬性的List, 并且list里面的Integer變?yōu)镾tring
? ? ? ? json = "{\"id\": \"000000\",\"types\": \"[{\\\"name\\\":\\\"name1\\\",\\\"list1\\\":[1,2]},{\\\"name\\\":\\\"name2\\\",\\\"list1\\\":[3,4]}]\",\"keywordIds1\": \"[12,13]\"}";
? ? ? ? System.out.println(json);
? ? ? ? requestParam = gson.fromJson(json, new TypeToken<RequestParams>() {}.getType());
? ? ? ? Assert.assertTrue(requestParam.getTypes().get(0).getClass().getName().indexOf("TypeItem") >= 0);
? ? ? ? System.out.println(gson.toJson(requestParam));
? ? }
? ? @Data
? ? public static class RequestParams {
? ? ? ? private String id;
? ? ? ? @JsonAdapter(CollectionStringTypeAdapterFactory.class)
? ? ? ? private List<TypeItem> types;
? ? ? ? @JsonAdapter(CollectionStringTypeAdapterFactory.class)
? ? ? ? private List<Integer> keywordIds;
? ? ? ? @JsonAdapter(CollectionStringTypeAdapterFactory.class)
? ? ? ? private List<String> keywordIds1;
? ? }
? ? @Data
? ? public static class TypeItem {
? ? ? ? private String name;
? ? ? ? private List<Integer> list;
? ? ? ? private List<String> list1;
? ? }

Gson注解

@SerializedName

主要應(yīng)用在Gson解析json字符串時(shí)。Gson能直接將json字符串解析成java對(duì)象或者集合,也能將java對(duì)象轉(zhuǎn)換為json字符串表示。例如有json數(shù)據(jù)如下:

{
? ? "id":"1"
? ? "n":"zhangsan"
? ? "p":"123456"
? ? "s":"0"
}

它能被解析到下面這個(gè)對(duì)象

public class User{
? ? private String id;
? ? private String n;
? ? private String p;
? ? private string s;
}

默認(rèn)在字段名相同的字段間解析,所以User類必須要這樣寫才能直接使用Gson解析出來,但是java對(duì)象里的屬性名和json里的字段名有時(shí)會(huì)不一樣。Gson提供注解的方法來解決這個(gè)問題。

public class User{
?
? ? private String id;
?
? ? @SerializedName("n")
? ? private String userName;
?
? ? @SerializedName("p")
? ? private String password;
?
? ? @SerializedName("s")
? ? private String sex;
}

Expose

通常與@SerializedName連用,當(dāng)我們不想把某個(gè)屬性包含到j(luò)son中時(shí)可以用。

public class UserSimple { ?
? ? @Expose()
? ? String name; // equals serialize & deserialize
?
? ? @Expose(serialize = false, deserialize = false)
? ? String email;?
?
? ? @Expose(serialize = false)
? ? int age;?
?
? ? @Expose(deserialize = false)
? ? boolean isDeveloper; // equals only serialize
}

序列化的結(jié)果將只有name和isDeveloper出現(xiàn)在json中,因?yàn)閟erialize都是false。反序列化時(shí),java對(duì)象將只會(huì)擁有json中的name和age,因?yàn)閐iserialze是true。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論