如何使用GSON或Java中的另一个JSON库反序列化列表?


121

我可以List<Video>在GAE的servlet中序列化一个,但不能反序列化它。我究竟做错了什么?

这是我在GAE中的视频课程,该课程已序列化:

package legiontube;

import java.util.Date;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Video {

    @PrimaryKey
    private String id;

    @Persistent
    private String titulo;

    @Persistent
    private String descricao;

    @Persistent
    private Date date;

    public Video(){};

 public Video(String id, String titulo, String descricao, Date date) {
  //super();
  this.id = id;
  this.titulo = titulo;
  this.descricao = descricao;
  this.date = date;
 }

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getTitulo() {
  return titulo;
 }

 public void setTitulo(String titulo) {
  this.titulo = titulo;
 }

 public String getDescricao() {
  return descricao;
 }

 public void setDescricao(String descricao) {
  this.descricao = descricao;
 }

 public Date getDate() {
  return date;
 }

 public void setDate(Date date) {
  this.date = date;
 }

}

这是我在其他应用程序中尝试反序列化的类Video。

package classes;

import java.util.Date;

public class Video {
 private String id;
 private String titulo;
 private String descricao;
 private Date date;

 public Video(String id, String titulo, String descricao, Date date) {
  //super();
  this.id = id;
  this.titulo = titulo;
  this.descricao = descricao;
  this.date = date;
 }

 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getTitulo() {
  return titulo;
 }
 public void setTitulo(String titulo) {
  this.titulo = titulo;
 }
 public String getDescricao() {
  return descricao;
 }
 public void setDescricao(String descricao) {
  this.descricao = descricao;
 }
 public Date getDate() {
  return date;
 }
 public void setDate(Date date) {
  this.date = date;
 }

}

仅供参考,从Gson 1.7开始,不再需要no-args构造函数。参见groups.google.com/group/google-gson/browse_thread/thread/…编码愉快。
乔尔

Answers:


328

使用Gson,您只需要执行以下操作:

List<Video> videos = gson.fromJson(json, new TypeToken<List<Video>>(){}.getType());

您可能还需要在Video要反序列化的类上提供no-arg构造函数。


杜德,您真了不起,非常感谢,它有效。我的错误是没有创建没有参数的构造函数。非常感谢!
Valter Silva

4
子句new TypeToken <List <Video >>(){}。getType()中的{}是什么?Java语法如何合法?
Maxim Veksler 2010年

8
@Maxim:它正在使...成为匿名子类,TypeToken<List<Video>>这是一个使结果类型能够表示的技巧List<Video>,因为完全指定的泛型类型的子类保留了泛型类型信息。
ColinD 2010年

1
Gson的2.1版本现在具有默认的访问构造函数...因此,我们不能使用上面的代码...而是现在TypeToken类具有以下方法:public static TypeToken <?> get(Type type){return new TypeToken(类型); }但是在这种情况下……我们如何为它提供正确的类型呢???
Pablo 2012年

1
@Pablo:在我看来,for的no-arg构造函数TypeToken仍在protectedGson 2.1中,因此上述内容仍然可以使用。
ColinD 2012年

108

另一种方法是将数组用作类型,例如:

Video[] videoArray = gson.fromJson(json, Video[].class);

这样就避免了使用Type对象的麻烦,并且如果您确实需要列表,可以随时将数组转换为列表,例如:

List<Video> videoList = Arrays.asList(videoArray);

恕我直言,这更具可读性。


科特林,它看起来像这样:

Gson().fromJson(jsonString, Array<Video>::class.java)

要将数组转换为List,只需使用.toList()方法


1
公认的答案是好的,但是我更喜欢这样做,因为我真正想要的只是一个东西列表,而数组足以充当“东西列表”
smac89 2015年


2

请小心使用@DevNG提供的答案。Arrays.asList()返回ArrayList的内部实现,该实现未实现一些有用的方法,例如add(),delete()等。如果调用它们,将抛出UnsupportedOperationException。为了获得真实的ArrayList实例,您需要编写如下代码:

List<Video> = new ArrayList<>(Arrays.asList(videoArray));

at?Arrays.asList返回一个List接口,该接口还提供add()和remove()!
Enrichman '16

2
@Enrichman:Arrays.asList()返回由指定数组支持的固定大小的列表。此ArrayList实现扩展了AbstractList类,并且不重写基类中的方法remove(int index)。而且,如果您查看AbstractList.remove(int index)的源代码,您会发现它始终抛出UnsupportedOperationException。add()方法也是如此。
Bogdan Kornev

1
哇,那真丑,我不知道。感谢您指出。:)
Enrichman '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.