2012-08-15 12 views
9

उम्मीद है कि JAXB विशेषज्ञों के लिए एक आसान एक:XmlJavaTypeAdapter का पता लगते ही नहीं

मैं अपरिवर्तनीय वर्ग करता है कि नहीं एक डिफ़ॉल्ट कोई आर्ग निर्माता को परिभाषित मार्शल करने के लिए कोशिश कर रहा हूँ। मैंने XmlAdapter कार्यान्वयन को परिभाषित किया है लेकिन ऐसा नहीं लगता है। मैंने एक सरल आत्मनिर्भर उदाहरण रखा है, जो अभी भी काम करने में असफल रहा है। क्या कोई सलाह दे सकता है कि मैं क्या गलत कर रहा हूं?

अपरिवर्तनीय कक्षा

@XmlJavaTypeAdapter(FooAdapter.class) 
@XmlRootElement 
public class Foo { 
    private final String name; 
    private final int age; 

    public Foo(String name, int age) { 
    this.name = name; 
    this.age = age; 
    } 

    public String getName() { return name; } 
    public int getAge() { return age; } 
} 

एडाप्टर और मूल्य प्रकार

public class FooAdapter extends XmlAdapter<AdaptedFoo, Foo> { 
    public Foo unmarshal(AdaptedFoo af) throws Exception { 
    return new Foo(af.getName(), af.getAge()); 
    } 

    public AdaptedFoo marshal(Foo foo) throws Exception { 
    return new AdaptedFoo(foo); 
    } 
} 

class AdaptedFoo { 
    private String name; 
    private int age; 

    public AdaptedFoo() {} 

    public AdaptedFoo(Foo foo) { 
    this.name = foo.getName(); 
    this.age = foo.getAge(); 
    } 

    @XmlAttribute 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 

    @XmlAttribute 
    public int getAge() { return age; } 
    public void setAge(int age) { this.age = age; } 
} 

Marshaller

public class Marshal { 
    public static void main(String[] args) { 
    Foo foo = new Foo("Adam", 34); 

    try { 
     JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class); 
     Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

     // output pretty printed 
     jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbMarshaller.marshal(foo, System.out);    
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

स्टैक ट्रेस

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 
Foo does not have a no-arg default constructor. 
     this problem is related to the following location: 
       at Foo 

     at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:451) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:283) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1142) 
     at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248) 
     at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235) 
     at javax.xml.bind.ContextFinder.find(ContextFinder.java:445) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584) 
     at Marshal2.main(Marshal2.java:11) 

ध्यान दें कि मैं JDK 1.7.0_05 उपयोग कर रहा हूँ।

उत्तर

7

निम्नलिखित की मदद करनी चाहिए:

FOO जड़ वस्तु के रूप में

@XmlJavaTypeAdapter प्रकार स्तर यह केवल उस वर्ग को संदर्भित क्षेत्रों/प्रॉपर्टी पर लागू होती पर निर्दिष्ट किया जाता है, और नहीं जब उस वर्ग का एक उदाहरण आपके एक्सएमएल पेड़ में एक मूल वस्तु है। इसका मतलब है कि आपको Foo को AdaptedFoo में परिवर्तित करना होगा, और JAXBContextAdaptedFoo पर Foo पर बनाना होगा।

मार्शल

package forum11966714; 

import javax.xml.bind.*; 

public class Marshal { 
    public static void main(String[] args) { 
     Foo foo = new Foo("Adam", 34); 

     try { 
     JAXBContext jaxbContext = JAXBContext.newInstance(AdaptedFoo.class); 
     Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

     // output pretty printed 
     jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbMarshaller.marshal(new AdaptedFoo(foo), System.out);    
     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 
    } 

AdaptedFoo

आप AdaptedFoo वर्ग के लिए एक @XmlRootElement टिप्पणी जोड़ने के लिए की आवश्यकता होगी। आप Foo कक्षा से एक ही एनोटेशन को हटा सकते हैं।

package forum11966714; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
class AdaptedFoo { 
    private String name; 
    private int age; 

    public AdaptedFoo() { 
    } 

    public AdaptedFoo(Foo foo) { 
     this.name = foo.getName(); 
     this.age = foo.getAge(); 
    } 

    @XmlAttribute 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlAttribute 
    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 
} 

FOO के रूप में नेस्टेड वस्तु

जब Foo जड़ वस्तु सब कुछ काम करता है जिस तरह से आप यह मैप किया गया है नहीं है। मैंने आपके मॉडल को यह दिखाने के लिए बढ़ाया है कि यह कैसे काम करेगा।

बार

package forum11966714; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bar { 

    private Foo foo; 

    public Foo getFoo() { 
     return foo; 
    } 

    public void setFoo(Foo foo) { 
     this.foo = foo; 
    } 

} 

डेमो

नोट JAXB संदर्भ कार्यान्वयन जब JAXBContext bootstrapping आप Foo वर्ग निर्दिष्ट नहीं दूँगा कि।

package forum11966714; 

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 
    public static void main(String[] args) { 
     try { 
      JAXBContext jaxbContext = JAXBContext.newInstance(Bar.class); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      File xml = new File("src/forum11966714/input.xml"); 
      Bar bar = (Bar) jaxbUnmarshaller.unmarshal(xml); 

      Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
      jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      jaxbMarshaller.marshal(bar, System.out); 
     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

input.xml/आउटपुट

<?xml version="1.0" encoding="UTF-8"?> 
<bar> 
    <foo name="Jane Doe" age="35"/> 
</bar> 
+1

धन्यवाद ब्लेज! (मुझे लगता है कि यह आपका ब्लॉग था जिसे मैं मूल रूप से देख रहा था)। ऐसा लगता है कि समस्या मैं बूटस्ट्रैपिंग के दौरान JAXBContext को Foo.class निर्दिष्ट कर रहा था। शर्म जेएक्सबी इस बिंदु पर काम नहीं करता है कि मैंने फू के लिए एडाप्टर निर्दिष्ट किया है ... बूटस्ट्रैपिंग को थोड़ा सा बनाता है। – Adamski

संबंधित मुद्दे