zoukankan      html  css  js  c++  java
  • JAXB

    For some Java container types JAXB has no built-in mapping to an XML structure. Also, you may want to represent Java types in a way that is entirely different from what JAXB is apt to do. Such mappings require an adapter class, written as an extension of XmlAdapter<XmlType,ApplType> from the package javax.xml.bind.annotation.adapters. The annotation XmlJavaTypeAdapter is provided for announcing the adapter in the desired place.

    We'll illustrate adapters by defining a substitution of a map for an array. Here is an XML example of the data we have to deal with.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns:training xmlns:ns="http://foo/bar">
        <brochure>
            <course price="123.45" id="c1">
                <name>Course 1</name>
            </course>
            <course price="123.45" id="c0">
                <name>Course 0</name>
            </course>
        </brochure>
    </ns:training>

    The course elements could be represented as a list or array, but we would like to process this data in our application as a map of the id attribute to the Course object. Although JAXB is capable of handling maps, we have seen (in section Top-level Elements: XmlRootElement) that the resulting XML structure isn't as simple as possible. To achieve our goal, we write a class Brochure containing the map we have in mind and declare that this is the one that has to be adapted to something JAXB knows how to handle, i.e., the classCourses containing a simple array of Course objects.

    @XmlRootElement(name="training")
    public class Training {
        @XmlElement
        public Brochure brochure;
        public Training(){}
        public Training( Brochure b ){
            brochure = b;
        }
    }
    
    @XmlJavaTypeAdapter(BrochureAdapter.class)
    public class Brochure {
        Map<String,Course> courses;
        public Brochure() {
            courses = new HashMap<String, Course>();
        }
    }
    
    public class Courses {
        @XmlElement(name="course")
        public Course[] carray;
    }
    
    public class Course {
        @XmlAttribute
        String id;
        @XmlElement
        String name;
        @XmlAttribute
        Price price;
    }

    Class Brochure is annotated with XmlJavaTypeAdapter, defining class BrochureAdapter as its adapter, and this is, of course, the interesting class. It has to override methodsunmarshal and marshal.

    public class BrochureAdapter extends XmlAdapter<Courses,Brochure> {
        @Override
        public Brochure unmarshal( Courses value ){
            Brochure b = new Brochure();
            for( Course c : value.carray )
                b.courses.put( c.id, c );
            return b;
        }
    
        @Override
        public Courses marshal( Brochure b ){
            Courses courses = new Courses();
            Collection<Course> c = b.courses.values();
            courses.carray = c.toArray(new Course[c.size()]);
            return courses;
        }
    }

    Courses is a class JAXB knows how to handle with respect to XML data, and the result of JAXB's innate capabilities is passed to the adaption for unmarshalling. In this method, we convert the data to a structure according to the desired class Brochure with its map. The reverse marshalling process has to convert a Brochure object with its map to a Courses object, which is easily done by putting the map values into an array.

    To summarize: XML binding happens against the class Courses, whereas application programming uses the Map type field courses in class Brochure.

  • 相关阅读:
    DirectX标准规定 DirectX和OpenGL的不同
    Android 抽屉效果的导航菜单实现
    Servlet基础(三) Servlet的多线程同步问题
    Java微服务之Spring Boot on Docker
    Spring Cloud 微服务架构学习笔记与示例
    从你的全世界路过—一群程序员的稻城亚丁游记
    从一个国内普通开发者的视角谈谈Sitecore
    吴军《硅谷来信》思维导图笔记
    .NET Core微服务之基于Jenkins+Docker实现持续部署(Part 1)
    2018OKR年中回顾
  • 原文地址:https://www.cnblogs.com/huey/p/5512353.html
Copyright © 2011-2022 走看看