Java에서 GSON 또는 다른 JSON 라이브러리를 사용하여 목록을 역 직렬화하는 방법은 무엇입니까?


121

List<Video>GAE의 서블릿에서 a 를 직렬화 할 수 있지만 역 직렬화 할 수 없습니다. 내가 뭘 잘못하고 있죠?

이것은 직렬화 된 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;
 }

}

이것은 비 직렬화를 시도하는 다른 응용 프로그램의 내 클래스 비디오입니다.

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부터는 인수가없는 생성자가 더 이상 필요하지 않습니다. groups.google.com/group/google-gson/browse_thread/thread/… 행복한 코딩을 참조하세요 .
Joel

답변:


328

Gson을 사용하면 다음과 같은 작업을 수행하면됩니다.

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

Video역 직렬화 할 클래스 에 인수가없는 생성자를 제공해야 할 수도 있습니다 .


야, 너 대단해, ​​정말 고마워. 내 실수는 인수가없는 생성자를 만들지 않았습니다. 정말 고맙습니다!
Valter Silva

4
new TypeToken <List <Video >> () {}. getType () 절의 {}는 무엇입니까? 합법적 인 자바 구문은 어떻습니까?
Maxim Veksler 2010

8
@Maxim : 익명의 하위 클래스를 만들고 있습니다 TypeToken<List<Video>>... List<Video>완전히 지정된 제네릭 유형의 하위 클래스가 제네릭 유형 정보를 유지하기 때문에 결과 유형 이을 나타낼 수 있도록하는 트릭입니다 .
ColinD 2010

1
2.1 버전의 Gson에는 이제 기본 액세스 생성자가 있습니다 ... 따라서 위의 코드를 사용할 수 없습니다 ... 대신 TypeToken 클래스에 다음 메서드가 있습니다. public static TypeToken <?> get (Type type) {return new TypeToken (유형); }하지만이 경우 ... 어떻게 올바른 유형을 제공 할 수 있습니까 ???
Pablo

1
@Pablo :의 인수가없는 생성자 TypeToken가 여전히 protectedGson 2.1에 있는 것처럼 보이 므로 위의 내용은 여전히 ​​작동합니다.
ColinD

108

또 다른 방법은 배열을 유형으로 사용하는 것입니다. 예 :

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

이렇게하면 Type 개체의 모든 번거 로움을 피할 수 있으며 목록이 정말로 필요한 경우 항상 배열을 목록으로 변환 할 수 있습니다. 예 :

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

IMHO 이것은 훨씬 더 읽기 쉽습니다.


에서 코 틀린 이 모습이 맘에 :

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

이 배열을 List로 변환하려면 .toList()방법을 사용하십시오.


1
받아 들여진 대답은 좋지만, 내가 정말로 원했던 것은 물건의 목록이고 배열은 "물건 목록"으로 사용하기에 충분하기 때문에 이것을 선호합니다
smac89

10

이 원 라이너를 사용해보십시오

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

경고 :에서 videos반환 된 목록 Arrays.asList은 변경할 수 없습니다. 새 값을 삽입 할 수 없습니다.


참고:

  1. 메서드 배열 #asList
  2. 생성자 Gson
  3. 메소드 Gson # fromJson (소스 json유형 JsonElementReader, 또는 String)
  4. 인터페이스 목록
  5. JLS-배열
  6. JLS-일반 인터페이스

2

@DevNG가 제공하는 답변을 사용하여주의하십시오. Arrays.asList ()는 add (), delete () 등과 같은 유용한 메서드를 구현하지 않는 ArrayList의 내부 구현을 반환합니다. 이러한 메서드를 호출하면 UnsupportedOperationException이 발생합니다. 실제 ArrayList 인스턴스를 얻으려면 다음과 같이 작성해야합니다.

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

와트? Arrays.asList는 add () 및 remove ()도 제공하는 List 인터페이스를 반환합니다!
Enrichman

2
@Enrichman : Arrays.asList ()는 지정된 배열이 지원하는 고정 크기 목록을 반환합니다. 이 ArrayList 구현은 AbstractList 클래스를 확장하며 기본 클래스의 remove (int index) 메서드를 재정의하지 않습니다. AbstractList.remove (int index)의 소스 코드를 보면 항상 UnsupportedOperationException이 발생하는 것을 볼 수 있습니다. add () 메서드도 마찬가지입니다.
Bogdan Kornev

1
와, 꽤 못 생겼어요. 몰랐어요. 지적 해 주셔서 감사합니다. :)
Enrichman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.