खोज…


परिचय

XML बाइंडिंग के लिए JAXB या Java Architecture (JAXB) एक सॉफ्टवेयर फ्रेमवर्क है जो जावा डेवलपर्स को जावा क्लासेस को XML एक्सपट्र्स पर मैप करने की अनुमति देता है। यह पेज पाठकों को JAXB के लिए विस्तृत उदाहरणों का उपयोग करते हुए विस्तृत रूप से उदाहरण देगा, जो मुख्य रूप से मार्शलिंग और अन-मार्शिंग जावा ऑब्जेक्ट्स के लिए xml प्रारूप में और इसके विपरीत दिए गए हैं।

वाक्य - विन्यास

  • JAXB.marshall (ऑब्जेक्ट, fileObjOfXML);

  • ऑब्जेक्ट obj = JAXB.unmarshall (fileObjOfXML, className);

पैरामीटर

पैरामीटर विवरण
fileObjOfXML File एक XML फ़ाइल की वस्तु
कक्षा का नाम .class एक्सटेंशन के साथ एक वर्ग का नाम

टिप्पणियों

JDK में उपलब्ध XJC टूल का उपयोग करके, xml स्कीमा ( .xsd फ़ाइल) में वर्णित xml संरचना के लिए जावा कोड अपने आप उत्पन्न हो सकता है, XJC विषय देखें।

XML फ़ाइल लिखना (किसी ऑब्जेक्ट को मार्श करना)

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class User {

    private long userID;
    private String name;
    
    // getters and setters
}

एनोटेशन XMLRootElement का उपयोग करके, हम एक वर्ग को XML फ़ाइल के मूल तत्व के रूप में चिह्नित कर सकते हैं।

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

public class XMLCreator {
    public static void main(String[] args) {
        User user = new User();
        user.setName("Jon Skeet");
        user.setUserID(8884321);

        try {
            JAXB.marshal(user, new File("UserDetails.xml"));
        } catch (Exception e) {
            System.err.println("Exception occurred while writing in XML!");
        } finally {
            System.out.println("XML created");
        }
    }
}

marshal() का उपयोग किसी XML फ़ाइल में ऑब्जेक्ट की सामग्री को लिखने के लिए किया जाता है। यहां user ऑब्जेक्ट और एक नई File ऑब्जेक्ट को marshal() तर्क के रूप में पारित किया जाता है।

सफल निष्पादन पर, यह नीचे दी गई सामग्री के साथ वर्ग-पथ में UserDetails.xml नामक एक XML फ़ाइल बनाता है।

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <name>Jon Skeet</name>
    <userID>8884321</userID>
</user>

XML फ़ाइल पढ़ना (अनमर्सहॉलिंग)

नीचे सामग्री के साथ UserDetails.xml नामक एक XML फ़ाइल को पढ़ने के लिए

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <name>Jon Skeet</name>
    <userID>8884321</userID>
</user>

हमें नीचे के रूप में User.java नाम का एक POJO वर्ग User.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class User {

    private long userID;
    private String name;

    // getters and setters
}

यहां हमने XML नोड्स के अनुसार चर और वर्ग नाम बनाए हैं। उन्हें मैप करने के लिए, हम क्लास पर एनोटेशन XmlRootElement उपयोग करते हैं।

public class XMLReader {
    public static void main(String[] args) {
        try {
            User user = JAXB.unmarshal(new File("UserDetails.xml"), User.class);
            System.out.println(user.getName());   // prints Jon Skeet
            System.out.println(user.getUserID()); // prints 8884321
        } catch (Exception e) {
            System.err.println("Exception occurred while reading the XML!");
        }
    }
}

यहाँ XML फाइल को पार्स करने के लिए unmarshal() विधि का उपयोग किया जाता है। यह XML फ़ाइल नाम और वर्ग प्रकार को दो तर्कों के रूप में लेता है। फिर हम डेटा को प्रिंट करने के लिए ऑब्जेक्ट के गेट्टर तरीकों का उपयोग कर सकते हैं।

वांछित xml प्रारूप उत्पन्न करने के लिए XmlAdapter का उपयोग करना

जब वांछित XML प्रारूप जावा ऑब्जेक्ट मॉडल से भिन्न होता है, तो एक XmlAdapter कार्यान्वयन मॉडल ऑब्जेक्ट को xml- प्रारूप ऑब्जेक्ट और इसके विपरीत में बदलने के लिए उपयोग किया जा सकता है। यह उदाहरण दर्शाता है कि फ़ील्ड के नाम के साथ किसी तत्व की विशेषता में फ़ील्ड के मान को कैसे रखा जाए।

public class XmlAdapterExample {

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class NodeValueElement {
          
        @XmlAttribute(name="attrValue")
        String value;
    
        public NodeValueElement() {
        }
    
        public NodeValueElement(String value) {
            super();
            this.value = value;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    }

    public static class ValueAsAttrXmlAdapter extends XmlAdapter<NodeValueElement, String> {        
        @Override
        public NodeValueElement marshal(String v) throws Exception {
            return new NodeValueElement(v);
        }
        
        @Override
        public String unmarshal(NodeValueElement v) throws Exception {
            if (v==null) return "";
            return v.getValue();
        }
    }

    @XmlRootElement(name="DataObject")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class DataObject {
        
        String elementWithValue;

        @XmlJavaTypeAdapter(value=ValueAsAttrXmlAdapter.class)
        String elementWithAttribute;
    }

    public static void main(String[] args) {
        DataObject data = new DataObject();
        data.elementWithValue="value1";
        data.elementWithAttribute ="value2";
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        JAXB.marshal(data, baos);

        String xmlString = new String(baos.toByteArray(), StandardCharsets.UTF_8);
        
        System.out.println(xmlString);
    }
}

स्वचालित फ़ील्ड / गुण XML मैपिंग कॉन्फ़िगरेशन (@XmlAccessorType)

एनोटेशन @XmlAccessorType यह निर्धारित करता है कि क्या फ़ील्ड / गुण XML में स्वचालित रूप से @XmlAccessorType होंगे। ध्यान दें, वह फ़ील्ड और विधि एनोटेशन @XmlElement , @XmlAttribute या @XmlTransient डिफ़ॉल्ट सेटिंग्स पर पूर्ववर्तीता लेते हैं।

public class XmlAccessTypeExample {

@XmlAccessorType(XmlAccessType.FIELD)
static class AccessorExampleField {
    public String field="value1";
    
    public String getGetter() {
        return "getter";
    }
    
    public void setGetter(String value) {}
}

@XmlAccessorType(XmlAccessType.NONE)
static class AccessorExampleNone {
    public String field="value1";
    
    public String getGetter() {
        return "getter";
    }
    
    public void setGetter(String value) {}
}

@XmlAccessorType(XmlAccessType.PROPERTY)
static class AccessorExampleProperty {
    public String field="value1";
    
    public String getGetter() {
        return "getter";
    }
    
    public void setGetter(String value) {}
}

@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
static class AccessorExamplePublic {
    public String field="value1";
    
    public String getGetter() {
        return "getter";
    }
    
    public void setGetter(String value) {}
}

public static void main(String[] args) {
    try {
        System.out.println("\nField:");
        JAXB.marshal(new AccessorExampleField(), System.out);
        System.out.println("\nNone:");
        JAXB.marshal(new AccessorExampleNone(), System.out);
        System.out.println("\nProperty:");
        JAXB.marshal(new AccessorExampleProperty(), System.out);
        System.out.println("\nPublic:");
        JAXB.marshal(new AccessorExamplePublic(), System.out);
    } catch (Exception e) {
        System.err.println("Exception occurred while writing in XML!");
    }
}

} // outer class end

उत्पादन

Field:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleField>
    <field>value1</field>
</accessorExampleField>

None:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleNone/>

Property:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleProperty>
    <getter>getter</getter>
</accessorExampleProperty>

Public:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExamplePublic>
    <field>value1</field>
    <getter>getter</getter>
</accessorExamplePublic>

मैनुअल फ़ील्ड / संपत्ति XML मैपिंग कॉन्फ़िगरेशन

एनोटेशन @XmlElement , @XmlAttribute या @XmlTransient और पैकेज javax.xml.bind.annotation में अन्य प्रोग्रामर को निर्दिष्ट करने की अनुमति देता है कि कौन से और कैसे चिह्नित फ़ील्ड्स या प्रॉपर्टीज़ को क्रमबद्ध किया जाना चाहिए।

@XmlAccessorType(XmlAccessType.NONE) // we want no automatic field/property marshalling
public class ManualXmlElementsExample {
    
    @XmlElement
    private String field="field value";

    @XmlAttribute
    private String attribute="attr value";
    
    @XmlAttribute(name="differentAttribute")
    private String oneAttribute="other attr value";
    
    @XmlElement(name="different name")
    private String oneName="different name value";
    
    @XmlTransient
    private String transientField = "will not get serialized ever";
    
    
    @XmlElement
    public String getModifiedTransientValue() {
        return transientField.replace(" ever", ", unless in a getter");
    }
    
    public void setModifiedTransientValue(String val) {} // empty on purpose


    public static void main(String[] args) {
        try {
            JAXB.marshal(new ManualXmlElementsExample(), System.out);
        } catch (Exception e) {
            System.err.println("Exception occurred while writing in XML!");
        }
    }
}

मौजूदा डेटा का उपयोग (पुनः) करने के लिए एक XmlAdapter उदाहरण निर्दिष्ट करना

कभी-कभी डेटा के विशिष्ट उदाहरणों का उपयोग किया जाना चाहिए। मनोरंजन वांछित नहीं है और static डेटा को संदर्भित करना एक कोड गंध होगा।

XmlAdapter उदाहरण निर्दिष्ट करना संभव है, Unmarshaller का उपयोग करना चाहिए, जो उपयोगकर्ता को XmlAdapter s का उपयोग करने की अनुमति देता है, जिसमें कोई शून्य- XmlAdapter कंस्ट्रक्टर और / या एडॉप्टर को डेटा पास नहीं करना चाहिए।

उदाहरण

उपयोगकर्ता वर्ग

निम्न वर्ग में एक नाम और एक उपयोगकर्ता की छवि है।

import java.awt.image.BufferedImage;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class User {
    
    private String name;
    private BufferedImage image;

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

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

    @XmlJavaTypeAdapter(value=ImageCacheAdapter.class)
    @XmlAttribute
    public BufferedImage getImage() {
        return image;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
    }

    public User(String name, BufferedImage image) {
        this.name = name;
        this.image = image;
    }

    public User() {
        this("", null);
    }

}

अनुकूलक

दो बार मेमोरी में एक ही छवि बनाने से बचने के लिए (साथ ही डेटा फिर से डाउनलोड करने के लिए), एडेप्टर छवियों को एक मानचित्र में संग्रहीत करता है।

जावा एसई 7

मान्य Java 7 कोड के लिए getImage पद्धति को बदलें

public BufferedImage getImage(URL url) {
    BufferedImage image = imageCache.get(url);
    if (image == null) {
        try {
            image = ImageIO.read(url);
        } catch (IOException ex) {
            Logger.getLogger(ImageCacheAdapter.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        imageCache.put(url, image);
        reverseIndex.put(image, url);
    }
    return image;
}
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ImageCacheAdapter extends XmlAdapter<String, BufferedImage> {

    private final Map<URL, BufferedImage> imageCache = new HashMap<>();
    private final Map<BufferedImage, URL> reverseIndex = new HashMap<>();

    public BufferedImage getImage(URL url) {
        // using a single lookup using Java 8 methods
        return imageCache.computeIfAbsent(url, s -> {
            try {
                BufferedImage img = ImageIO.read(s);
                reverseIndex.put(img, s);
                return img;
            } catch (IOException ex) {
                Logger.getLogger(ImageCacheAdapter.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        });
    }

    @Override
    public BufferedImage unmarshal(String v) throws Exception {
        return getImage(new URL(v));
    }

    @Override
    public String marshal(BufferedImage v) throws Exception {
        return reverseIndex.get(v).toExternalForm();
    }

}

एक्सएमएल उदाहरण

जॉन स्कीट और उनकी पृथ्वी 2 समकक्ष के लिए निम्नलिखित 2 xmls हैं, जो दोनों बिल्कुल एक जैसे दिखते हैं और इसलिए एक ही अवतार का उपयोग करते हैं।

<?xml version="1.0" encoding="UTF-8"?>

<user name="Jon Skeet" image="https://www.gravatar.com/avatar/6d8ebb117e8d83d74ea95fbdd0f87e13?s=328&amp;d=identicon&amp;r=PG"/>
<?xml version="1.0" encoding="UTF-8"?>

<user name="Jon Skeet (Earth 2)" image="https://www.gravatar.com/avatar/6d8ebb117e8d83d74ea95fbdd0f87e13?s=328&amp;d=identicon&amp;r=PG"/>

एडेप्टर का उपयोग करना

ImageCacheAdapter adapter = new ImageCacheAdapter();

JAXBContext context = JAXBContext.newInstance(User.class);

Unmarshaller unmarshaller = context.createUnmarshaller();

// specifiy the adapter instance to use for every
// @XmlJavaTypeAdapter(value=ImageCacheAdapter.class)
unmarshaller.setAdapter(ImageCacheAdapter.class, adapter);

User result1 = (User) unmarshaller.unmarshal(Main.class.getResource("user.xml"));

// unmarshal second xml using the same adapter instance
Unmarshaller unmarshaller2 = context.createUnmarshaller();
unmarshaller2.setAdapter(ImageCacheAdapter.class, adapter);
User result2 = (User) unmarshaller2.unmarshal(Main.class.getResource("user2.xml"));

System.out.println(result1.getName());
System.out.println(result2.getName());

// yields true, since image is reused
System.out.println(result1.getImage() == result2.getImage());

XML नाम स्थान को एक क्रमबद्ध जावा वर्ग में बांधना।

यह एक package-info.java फ़ाइल का एक उदाहरण है जो XML नाम स्थान को क्रमबद्ध जावा वर्ग में बांधता है। इसे उसी पैकेज में रखा जाना चाहिए, जिसमें जावा क्लासेस को नामस्थान का उपयोग करके क्रमबद्ध किया जाना चाहिए।

/**
 * A package containing serializable classes.
 */
@XmlSchema
(
    xmlns =
    {
        @XmlNs(prefix = MySerializableClass.NAMESPACE_PREFIX, namespaceURI = MySerializableClass.NAMESPACE)
    },
    namespace = MySerializableClass.NAMESPACE,
    elementFormDefault = XmlNsForm.QUALIFIED
)
package com.test.jaxb;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

स्ट्रिंग को ट्रिम करने के लिए XmlAdapter का उपयोग करना।

package com.example.xml.adapters;

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

public class StringTrimAdapter extends XmlAdapter<String, String> {
    @Override
    public String unmarshal(String v) throws Exception {
        if (v == null)
            return null;
        return v.trim();
    }

    @Override
    public String marshal(String v) throws Exception {
        if (v == null)
            return null;
        return v.trim();
    }
}

और पैकेज-info.java में निम्नलिखित घोषणा जोड़ें।

@XmlJavaTypeAdapter(value = com.example.xml.adapters.StringTrimAdapter.class, type = String.class)
package com.example.xml.jaxb.bindings;// Packge where you intend to apply trimming filter

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


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow