2011-12-06 2 views
4

나는 내 필요에 따라 작동하도록 @XMLJavaTypeAdapter을 갖기 위해 애썼다. 나는 내 이해가 잘못 될 수있다. 더 나은 방법으로 이해하도록 도와주세요.JAXB @XmlJavaTypeAdapter usage

요구 사항 : 예를 들어 : 내가 매핑의 목록을 전송 XML을 아래와 같이 오브젝트 : JAXB를 사용

<transport> 
    <mappings> 
     <product>XXX</product> 
     <eventName>XXX</eventName> 
     <destination>XXX</destination> 
     <destinationType>XXX</destinationType> 
    </mappings> 
</transport> 

, 나는 List<Mappings> 객체로 XML을 읽을 수 있어요.

메모리 내 표시가 List<Mappings>이고 코드가 List<Mapping>Map<String,Mappings>으로 매핑하려면 eventName과 내 코드 맵에서 사용하십시오.

저는 약간 @XmlJavaTypeAdapter의 사용법과 혼동되어서 어떻게 알아낼 수 없습니까?

이와 관련하여 도움을 주시면 감사하겠습니다.

감사 주권

답변

7

참고 :은 내가 EclipseLink JAXB (MOXy) 리드와 JAXB 2 (JSR-222) 전문가 그룹의 구성원입니다.

당신은 다음을 수행 MOXY의 @XmlPath 확장을 활용할 수 :

운송

Transport 클래스는 @XmlPath 확장을 사용합니다. @XmlPath이 없으면 mappings이라는 그룹 구성 요소가 문서에 추가됩니다.

package forum8403623; 

import java.util.*; 
import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import org.eclipse.persistence.oxm.annotations.XmlPath; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Transport { 

    @XmlJavaTypeAdapter(MappingsAdapter.class) 
    @XmlPath(".") 
    private Map<String, Mapping> mappings = new HashMap<String, Mapping>(); 

} 

매핑

package forum8403623; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(propOrder={"product", "eventName", "destination", "destinationType"}) 
public class Mapping { 

    String product; 
    String eventName; 
    String destination; 
    String destinationType; 

} 

MappingsAdapter

다음 클래스는 우리가 XML 매핑에 사용하게 될 표현으로 Map<String, Mapping>로/변환 할 책임이 있습니다.

이 JAXB 공급자로 MOXY을 사용하려면

package forum8403623; 

import java.util.*; 
import java.util.Map.Entry; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class MappingsAdapter extends XmlAdapter<MappingsAdapter.AdaptedMap, Map<String, Mapping>>{ 

    @Override 
    public Map<String, Mapping> unmarshal(AdaptedMap v) throws Exception { 
     Map<String, Mapping> mappings = new HashMap<String, Mapping>(); 
     for(Mapping mapping : v.mappings) { 
      mappings.put(mapping.product, mapping); 
     } 
     return mappings; 
    } 

    @Override 
    public AdaptedMap marshal(Map<String, Mapping> v) throws Exception { 
     AdaptedMap adaptedMap = new AdaptedMap(); 
     for(Entry<String,Mapping> entry : v.entrySet()) { 
      adaptedMap.mappings.add(entry.getValue()); 
     } 
     return adaptedMap; 
    } 

    static class AdaptedMap { 
     public List<Mapping> mappings = new ArrayList<Mapping>(); 
    } 
} 

데모

package forum8403623; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

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

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum8403623/input.xml"); 
     Transport transport = (Transport) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(transport, System.out); 
    } 

} 

jaxb.properties 당신은 JAXB라는 파일을 추가해야합니다.다음 항목으로 도메인 모델과 동일한 패키지에 속성 : 대한

javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory 

추가 정보

+0

첫째, 감사합니다 너의 빠른 응답 위트 h 우수 사례. 정말 고맙습니다. 위에서 언급 한 것과 동일한 단계를 수행하고 System.out 문을 거의 추가하지 않으면 Adapter의 marshall/unmarshall 메서드가 호출되는 것을 볼 수 있습니다. 불행히도 출력은 항상 빈 XML입니다. XML을 사용하여 Unmarhshalling Transport 객체에서 MappingsAdapter.AdaptedMap List가 채워지지 않는 것처럼 보입니다. 내가 잘못하고있는 것이 있습니까? 제발 조언. 다시 한 번 귀하의 도움과 인내심에 감사드립니다. Raj – Raj

+0

@Raj - 예제와 똑같이 사용하려면 클래스 경로에 eclipselink.jar가 있어야합니다. http://www.eclipse.org/eclipselink/downloads/에서 얻을 수 있습니다. JAXB 참조 구현을 사용하는 경우 다음 기사가 유용 할 수 있습니다. http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html –

+0

첫 번째 블로그 링크 +1 "XmlAdapter - JAXB의 비밀 무기 " – KNU