2011-09-24 5 views
20

일부 개체에 JSON 직렬화를 구현해야하며 제네릭 컬렉션과 통합 할 때 문제가 발생했습니다.자바 JSON 직렬화 - 모범 사례

모든 직렬화 가능 클래스 것은 (된 JSONObject는 this 라이브러리에서 제공)이 인터페이스를 구현 :

java.util.List가 더 많거나 적은 같은 외모를 기반으로 내 컬렉션에 대한
interface JSONSerializable{ 
    public JSONObject dump() throws JSONException //serializes object 
    public void load(JSONObject obj) throws JSONException //deserializes object 
} 

코드 :

class AwesomeList<T extends JSONSerializable> implements JSONSerializable{ 
    private LinkedList<T> items = new LinkedList<T>(); 
    ... 
    ... 

    public JSONObject dump() throws JSONException { 
     JSONObject result = new JSONObject(); 
     JSONArray a = new JSONArray(); 
     for(T i : items){ 
      a.put(i.dump()); 
     } 
     result.put("items", a); 
     return result; 
    } 

    public void load(JSONObject obj) throws JSONException{ 
     //here is my problem 
    } 
} 

내 문제는 : JSONObject에서 AwesomeList를로드 할 때 요소 작성이 필요하지만 Java에서 쓰기를 금지하기 때문에 불가능합니다.

T newItem = new T(); 
newItem.load(obj); 

이 작업에 대한 접근 방식을 어떻게 수정해야합니까?

+0

는 솔직히 말해서 난이도 알려진 작동 표시되지 않습니다 (자바 및 JSON) JSON, 당신은 (꽤 인쇄) JSON 형식으로 사용할 수있는 자바의 직렬화에 추가

유형. 클래스 이름을 JSON 데이터 패킷에 저장 하시겠습니까? – Perception

+0

아니요, 모든 객체는 JSONObject에서 자체를로드하는 방법을 알고 있습니다 (실제로는 연관 배열입니다). 나는 내가하고 싶은 것을 보여주기 위해 글을 업데이트했다. – KCH

답변

30

이 라이브러리에 묶여 있습니까? Google Gson은 매우 유명합니다. 제네릭과 함께 사용하지는 않았지만 프론트 페이지에서는 Gson이 Generics에 대한 지원을 매우 중요하다고 생각한다고 말합니다.

+2

gson은 제네릭을 잘 처리 할 수 ​​있습니다. – kingori

+3

마지막으로 gson이 순환 참조를 처리하지 않는다는 것을 확인했습니다 .. 업데이트로 해결할 수 있었지만 .. [link] http://jackson.codehaus.org/를 찾았습니다. gson에서 generic을 사용하여 json 변환을 수행하는 방법에 대해이 질문을 확인하십시오. [링크] http://stackoverflow.com/questions/5528385/json-conversion-using-gson –

+0

GSON의 사용법은 매우 간단하고 매우 간단합니다. – schmijos

0

글쎄, 파일에 쓸 때 T 클래스가 무엇인지 알기 때문에 dump에 저장할 수 있습니다. 그런 다음이를 다시 읽을 때 동적으로 리플렉션을 사용하여 호출 할 수 있습니다.

public JSONObject dump() throws JSONException { 
    JSONObject result = new JSONObject(); 
    JSONArray a = new JSONArray(); 
    for(T i : items){ 
     a.put(i.dump()); 
     // inside this i.dump(), store "class-name" 
    } 
    result.put("items", a); 
    return result; 
} 

public void load(JSONObject obj) throws JSONException { 
    JSONArray arrayItems = obj.getJSONArray("items"); 
    for (int i = 0; i < arrayItems.length(); i++) { 
     JSONObject item = arrayItems.getJSONObject(i); 
     String className = item.getString("class-name"); 
     try { 
      Class<?> clazzy = Class.forName(className); 
      T newItem = (T) clazzy.newInstance(); 
      newItem.load(obj); 
      items.add(newItem); 
     } catch (InstantiationException e) { 
      // whatever 
     } catch (IllegalAccessException e) { 
      // whatever 
     } catch (ClassNotFoundException e) { 
      // whatever 
     } 
    } 
4

다른 사람들도 암시하는 것처럼 org.json의 라이브러리를 덤프하는 것을 고려해야합니다. 요즘에는 꽤 쓸모 없으며 문제를 해결하기 위해 노력하는 것은 시간 낭비입니다.

하지만 특정 질문에; 타입 변수 T는 컴파일 타임 정보 라기보다는 도움이되는 정보가 없습니다. 대신 실제 클래스를 'Class cls'인수로 전달해야하므로 'cls.newInstance()'를 사용하여 인스턴스를 만들 수 있습니다.

0

json-io (https://github.com/jdereg/json-io)를 사용해 보았습니까?

이 라이브러리는주기가있는 객체 그래프 (예 : A-> B, B-> A)를 포함하여 모든 Java 객체 그래프를 직렬화/비 직렬화 할 수있게합니다. 클래스가 특정 인터페이스를 구현하거나 특정 Java 클래스를 상속하지 않아도됩니다.

String niceFormattedJson = JsonWriter.formatJson(jsonString)