OXM: JAXB2.0 in JDK1.6

 

1.1.1 JAXB 2.0: ObjectàXML

Using JAXB 2.0 embedded in JDK 1.6.

Marshal Object to XML bytes:

      public byte[] marshalToBytes(Object o) throws Exception {

            JAXBContext context = JAXBContext.newInstance(o.getClass());

 

            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            Marshaller m = context.createMarshaller();

            m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); //set XML encoding.

            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //output formatted xml.

            m.setProperty(Marshaller.JAXB_FRAGMENT, false);// ignore XML header or not.

            m.marshal(o, bos);

 

            return bos.toByteArray();

      }

If you want to output XML to specific file, please udpate "ByteArrayOutputStream bos" to write XML into external file.

1.1.2 Object class should have empty constructor

 

1.1.3 @XmlTransient to ignore some properties

Some temporary data or some cycle reference relation.

 

For example, DDFNode.parentDDFNode.

 

1.1.4 @XmlJavaTypeAdapter

@XmlJavaTypeAdapter is used to adapter complex Object which is not recognized by JAXB into a simple or customized Object.

1) XmlAdapter.marshal(BoundType):

a. Convert Object to another ValueType which is recognized by JAXB. Or Which is customized rather than JAXB.

b. Used when ObjectàXml

2) XmlAdapter.unmarshal(ValueType):

a. Convert ValueType Object to java Object requested by business logical.

b. Used when XmlàObject

 

“List<String> tacs” instead of “Set tacs”

 

@XmlJavaTypeAdapter on field will lead to additional container tag. For example:

@XmlJavaTypeAdapter(FileNamesAdapter.class)

Map<String, String> profileMappings;

Will lead to XML like following:

           

            < profileMappings >

                        <profile-mapping …/>

                        <!--your wrapper xml element-->;

            </ profileMappings >

But not:

            <profile-mapping …/>

 

It’s better to use List<> as collection implementation. And all the Object use simple type.

 

There should be dedicated Xml Java adapter for DDFNode, because:

1) DFPropterties is dedicated complex element

2) Some elements have empty tag

3) List of child Nodes

4) …

 

1.1.5 @XmlType: Order of the Element:  @XmlType(propOrder = {“parameterNames”})

Use field name but not element name.

All the fields should be specified, even some of them are ignored by @XmlTransient.

1.1.6 Do not set CYCLE reference on Objects.

Normally, JAXB can detect the cycle reference problem.

1.1.7 @XmlSeeAlso: used to bind related InteriorDDFNode and LeafDDFNode

@XmlSeeAlso({InteriorDDFNode.class, LeafDDFNode.class})

public abstract class DDFNode extends IdClass {

           

}

@XmlSeeAlso can be used to link the bund to its related subclasses. It will be used to define InteriorDDFNode and LeafDDFNode. Because DDFTree use following definition:

    @XmlElement(name = "Node")

    private List<DDFNode> ddfNodes;

 

 

1.1.8 @XmlElementWrapper or not

@XmlElementWrapper is used to add a container tag for list,

For model/ddf, model/profile-mapping, there is no @XmlElementWrapper.

But for ddf*.xml, @XmlElementWrapper is used to define container, such as Node/DFProperties/AccessType(Get?, Add?, …).

1.1.9 @XmlSeeAlso + @XmlJavaTypeAdapter = what will happen????

 

1.1.10 @XmlElements + @XmlJavaTypeAdapter to generate DDFNode/DFProperties

There is no dedicated DFProperties bean object inside DDFNode.java.

Information for DFProperties are dynamic and has different value types.

 

Use XmlJavaTypeAdapter convert String value list to AccessType Object List:

                        List<AccessTypeBase> accessTypes = new ArrayList<AccessTypeBase>();

                        for (String access : b.accessTypes) {

                                    if (access.equalsIgnoreCase(AccessTypeAdd.ACCESS)) {

                                                accessTypes.add(new AccessTypeAdd());

                                    } else if (access.equalsIgnoreCase(AccessTypeCopy.ACCESS)) {

                                                accessTypes.add(new AccessTypeCopy());

                                    } else if (access.equalsIgnoreCase(AccessTypeDelete.ACCESS)) {

                                                accessTypes.add(new AccessTypeDelete());

                                    } else if (access.equalsIgnoreCase(AccessTypeExec.ACCESS)) {

                                                accessTypes.add(new AccessTypeExec());

                                    } else if (access.equalsIgnoreCase(AccessTypeReplace.ACCESS)) {

                                                accessTypes.add(new AccessTypeReplace());

                                    } else {

                                                accessTypes.add(new AccessTypeGet());

                                    }

                        }

 We can also use Map<accessTyeString, classNameString> to ignore many if...else....

 

Define XmlElements according to different Access Type class instance:

            @XmlElementWrapper(name = "AccessType")

            @XmlElements( {

                        @XmlElement(name="Add",type=AccessTypeAdd.class),

                        @XmlElement(name="Copy",type=AccessTypeCopy.class),

                        @XmlElement(name="Delete",type=AccessTypeDelete.class),

                        @XmlElement(name="Exec",type=AccessTypeExec.class),

                       @XmlElement(name="Get",type=AccessTypeGet.class),

                       @XmlElement(name="Replace",type=AccessTypeReplace.class)

            })

            public List<AccessTypeBase> accessTypes;

 

Then it will generate the XML format like following:

        <AccessType>

            <Get/>

            <Add/>

            <Replace/>

        </AccessType>

 

你可能感兴趣的:(jdk,bean,xml,Access)