Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。
对象转为字符串
String ps =gson.toJson(person);
字符串转为对象
Person person =gson.fromJson(json, Person.class);
字符串为为list,
List<Person> persons =gson.fromJson(json, new TypeToken<List<Person>>() {}.getType());
这里返回的数据类型是com.google.gson.internal.LinkedTreeMap,如果直接使用会报classCastException:com.google.gson.internal.LinkedTreeMap cannotbecasttocom.yzd.enation.entity.request.AcceptRequest$MaterialTakeInfoListEntity
下面二模块会讲解解决方法;
对象转为字符串,以键值对的方式返回字符串,
字符串转为对象,要注意字符串的格式。格式与对象转换的字符串一样,可以参照。
注意:
需要jar包 gson-2.3.jar,可从gson的官方下载所需版本。
字符串转为对象时,""字符串转出来对象为null,"{}" 转出来有对象,但各个字段为空值。
对象内有list字段时,json字符串的写法
json = "{\"id\":2,\"name\":\"abc\",\"books\":[\"xiqu\",\"wenzhang\",\"xiaoshuo\"]}";
json为list的写法
json = "[{\"id\":2,\"name\":\"abc\",\"books\":[\"xiqu\",\"wenzhang\",\"xiaoshuo\"]},"
+ "{\"id\":3,\"name\":\"def\",\"books\":[\"dianshi\",\"wenzhang\",\"xiaoshuo\"]}]";
代码示例:
import java.util.LinkedList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
class Person {
private long id;
private String name;
private List<String> books;
public Person(long id, String name) {
this.id = id;
this.name = name;
}
public Person(long id, String name, List<String> books) {
this(id, name);
this.books = books;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getBooks() {
return books;
}
public void setBooks(List<String> books) {
this.books = books;
}
public String toString(){
return "Person : { id=" + this.id + " name=" + this.name + " books=" + this.books + " }";
}
}
public class Gsontest {
static Gson gson = new Gson();
public static void main(String[] args) {
toJson();
fromJson();
}
static void toJson() {
List<String> books = new LinkedList<String>();
books.add("abook");
books.add("bbook");
books.add("cbook");
Person person = new Person(1, "xiao", books);
// 将一个对象转为以键值对表示的字符串,对象内可包含list等都可以
String ps = gson.toJson(person);
System.out.println(ps);
// 将一个对象List 转为以键值对表示的字符串
List<Person> persons = new LinkedList<Person>();
persons.add(person);
persons.add(new Person(2, "ming", books));
System.out.println(gson.toJson(persons));
}
static void fromJson() {
// 空字符串转出来对象为null
String json = "";
// 提供两个参数,分别是json字符串以及需要转换对象的类型。
Person person = gson.fromJson(json, Person.class);
System.out.println(person);
// 注:字符串必须在{}内,list类型包含在[]内,否则转换失败抛异常
json = "{}";
// {}内无内容,可以转换成对象,对象不为空,但是各个字段没有值
person = gson.fromJson(json, Person.class);
System.out.println(person);
// 注意键值对的写法,如果转换出错,很可能是写法不对,写法可以参照由 toJson 转出来的字符串.
json = "{\"id\":2,\"name\":\"abc\",\"books\":[\"xiqu\",\"wenzhang\",\"xiaoshuo\"]}";
person = gson.fromJson(json, Person.class);
System.out.println(person);
// TypeToken,它是gson提供的数据类型转换器,可以支持各种数据集合类型转换
json = "[{\"id\":2,\"name\":\"abc\",\"books\":[\"xiqu\",\"wenzhang\",\"xiaoshuo\"]},"
+ "{\"id\":3,\"name\":\"def\",\"books\":[\"dianshi\",\"wenzhang\",\"xiaoshuo\"]}]";
List<Person> persons = gson.fromJson(json, new TypeToken<List<Person>>() {
}.getType());
System.out.println(persons);
}
}
参考原文链接:https://blog.csdn.net/bingqilin_/article/details/48341093
二,泛型方法 Gson解析 com.google.gson.internal.LinkedTreeMap cannot be cast to XXX
今天遇到问题:明明返回的是自己定义的对象,结果使用时总是报:
classCasteException:
com.google.gson.internal.LinkedTreeMap cannotbecasttocom.yzd.enation.entity.request.AcceptRequest$MaterialTakeInfoListEntity
类转换异常:
百度一下后知道原因了:
先说说我这里的原代码片段:
public <T> List<T> getDataList(String tag) {
List<T> datalist=new ArrayList<T>();
String strJson = preferences.getString(tag, null);
if (null == strJson) {
return datalist;
}
Gson gson = new Gson();
datalist = gson.fromJson(strJson, new TypeToken<List<T>>() {
}.getType());
return datalist;
}
修改后的代码片段:
public <T> List<T> getDataList(String message, Class<T> cls){ //这里是Class<T>
List<T> list = new ArrayList<>();
String strJson = preferences.getString(message, null);
if (null == strJson) {
return list;
}
JsonArray jsonArray = new JsonParser().parse(strJson).getAsJsonArray();
Gson gson = new Gson();
for (JsonElement jsonElement : jsonArray) {
list.add(gson.fromJson(jsonElement,cls));
}
return list;
}
从网上参考了一些资料如下,解决的;https://blog.csdn.net/github_38222176/article/details/79198886
今天在尝试用泛型写json解析方法的时候出现了问题,看错误信息就是‘类型’转换问题。调试断点,果然发现这LinkedTreeMap有点不同,如下:
如果代码这样写:
public static <T> List<T> jsonToDto(String message, String jsonHead,T t){//这里是用的T
JsonObject jsonObject = new JsonParser().parse(message).getAsJsonObject();
JsonArray jsonArray = jsonObject.getAsJsonArray(jsonHead);
Gson gson = builder.create();
List<T> list = new ArrayList<>();
for (JsonElement jsonElement : jsonArray) {
t = gson.fromJson(jsonElement,new TypeToken<T>(){}.getType()); // TypeToken
list.add(t);
}
return list;
}
对应的结果如下:
解释TypeToken
如果这样写:
public static <T> List<T> jsonToDto(String message, String jsonHead,Class<T> cls){ //这里是Class<T>
JsonObject jsonObject = new JsonParser().parse(message).getAsJsonObject();
JsonArray jsonArray = jsonObject.getAsJsonArray(jsonHead);
Gson gson = builder.create();
List<T> list = new ArrayList<>();
for (JsonElement jsonElement : jsonArray) {
list.add(gson.fromJson(jsonElement,cls)); //cls
}
return list;
}
对应的结果如下:
20180129191919619.png
可以看出两种方法解析的结果的结构是不一样的,让我们来看一看下图:
20180130091155086.png
有两个方法对应我上述两段代码,返回类型都是T,当使用第一种方法时返回的是LinkedTreeMap,所以当我把解析后的集合遍历赋值给JavaBean的时候就会报“类型”转换错误的异常。解决方法就是使用第二种方法。或者参考LinkedTreeMap的处理方法
for (TestBean bean : list) {
....
}
网友评论