如何使用GSON或Java中的其他JSON库反序列化列表?

How to deserialize a list using GSON or another JSON library in Java?

我可以在GAE上的servlet中序列化一个列表,但不能反序列化它。我做错什么了?

这是我在GAE中的课堂视频,它是序列化的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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;

 /**
  * @param id
  * @param titulo
  * @param descricao
  * @param 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;
 }

}

这是我在另一个应用程序中的类视频,我尝试反序列化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package classes;

import java.util.Date;

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

 /**
  * @param id
  * @param titulo
  * @param descricao
  * @param 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
List<Video> videos = gson.fromJson(json, new TypeToken<List<Video>>(){}.getType());

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


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

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

这样可以避免类型对象带来的所有麻烦,如果您确实需要一个列表,则可以始终将数组转换为列表,例如:

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

imho这是更可读的。


试试这个衬垫

1
List<Video> videos = Arrays.asList(new Gson().fromJson(json, Video[].class));

警告:由Arrays.asList返回的videos列表是不可变的-不能插入新值。

参考文献:

  • 方法数组aslist
  • 建造商GSON
  • 方法gson-fromjson(来源json可以是JsonElement型、Reader型或String型)
  • 接口表
  • JLS阵列
  • JLS-通用接口

  • 小心使用@devng提供的答案。arrays.aslist()返回未实现某些有用方法(如add()、delete()等)的arraylist的内部实现。如果调用它们,将引发UnsupportedOperationException。要获得真正的ArrayList实例,需要编写如下内容:

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


    Jackson JSON Java解析器在Spring框架中非常流行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import java.io.IOException;
    import java.io.StringWriter;
    import java.util.List;

    import com.fasterxml.jackson.core.JsonGenerationException;
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;

    public static <T> T jsonStringToObjectArray(String jsonString, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
            T obj = null;
            ObjectMapper mapper = new ObjectMapper();
            mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
            obj = mapper.readValue(jsonString, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
            return obj;
        }