2012-03-25 3 views

답변

0

참고 : 저는 EclipseLink JAXB (MOXy)의 선두 주자이며 JAXB 2 (JSR-222) 전문가 그룹의 구성원입니다.

오브젝트 -JSON 바인딩 접근법에 관심이있는 경우 아래에 MOXy를 사용하여 수행 할 수있는 방법이 나와있다. 예 아래 JSPON 코어 규격에서 한 예에 기초한다 :

부모

Parent 클래스 JSON의 루트에 해당 도메인 목적 메시지. 두 개의 필드는 Child입니다.

package forum9862100; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Parent { 

    protected Child field1; 
    protected Child field2; 

} 

Child 클래스의 키에 의해 참조 될 수

아이. 이 유스 케이스는 XmlAdapter으로 처리 할 것입니다. @XmlJavaTypeAdapter 주석을 사용하여 XmlAdapter에 링크됩니다.

package forum9862100; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlJavaTypeAdapter(ChildAdapter.class) 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Child { 

    protected String id; 
    protected String foo; 
    protected Integer bar; 

} 

ChildAdapter 아래

XmlAdapter의 구현입니다. 이 XmlAdapter은 상태 저장이므로 MarshallerUnmarshaller에 인스턴스를 설정해야합니다.

package forum9862100; 

import java.util.*; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class ChildAdapter extends XmlAdapter<ChildAdapter.AdaptedChild, Child>{ 

    private List<Child> childList = new ArrayList<Child>(); 
    private Map<String, Child> childMap = new HashMap<String, Child>(); 

    public static class AdaptedChild extends Child { 
     @XmlElement(name="$ref") 
     public String reference; 
    } 

    @Override 
    public AdaptedChild marshal(Child child) throws Exception { 
     AdaptedChild adaptedChild = new AdaptedChild(); 
     if(childList.contains(child)) { 
      adaptedChild.reference = child.id; 
     } else { 
      adaptedChild.id = child.id; 
      adaptedChild.foo = child.foo; 
      adaptedChild.bar = child.bar; 
      childList.add(child); 
     } 
     return adaptedChild; 
    } 

    @Override 
    public Child unmarshal(AdaptedChild adaptedChild) throws Exception { 
     Child child = childMap.get(adaptedChild.reference); 
     if(null == child) { 
      child = new Child(); 
      child.id = adaptedChild.id; 
      child.foo = adaptedChild.foo; 
      child.bar = adaptedChild.bar; 
      childMap.put(child.id, child); 
     } 
     return child; 
    } 

} 

데모

아래 코드는 MarshallerUnmarshaller의 상태 XmlAdapter 지정하는 방법을 보여줍니다

package forum9862100; 

import java.io.File; 
import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Parent.class); 

     StreamSource json = new StreamSource(new File("src/forum9862100/input.json")); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     unmarshaller.setProperty("eclipselink.media-type", "application/json"); 
     unmarshaller.setProperty("eclipselink.json.include-root", false); 
     unmarshaller.setAdapter(new ChildAdapter()); 
     Parent parent = (Parent) unmarshaller.unmarshal(json, Parent.class).getValue(); 

     System.out.println(parent.field1 == parent.field2); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.setProperty("eclipselink.media-type", "application/json"); 
     marshaller.setProperty("eclipselink.json.include-root", false); 
     marshaller.setAdapter(new ChildAdapter()); 
     marshaller.marshal(parent, System.out); 
    } 

} 

출력 아래

실행의 출력입니다 민주당 코드. Child의 두 인스턴스가 신원 확인 테스트를 통과 한 방법에 유의하십시오.추가 정보

true 
{ 
    "field1" : { 
     "id" : "2", 
     "foo" : "val", 
     "bar" : 4 
    }, 
    "field2" : { 
     "$ref" : "2" 
    }} 

이 대단한

+1

은 자세한 답변을 주셔서 감사합니다! – user842800

0

많은 Object to JSon 직렬화 라이브러리 중 하나를 사용할 것입니다. 라이브러리의 대부분은 확장 성이 있지만 참조를 추가하는 것이 언제 사용할 것인지에 대한 실질적인 선택을하지 않으면 복잡해 질 수 있습니다.

관련 문제