george.gu 发表于 2013-1-29 22:18:57

OXM: JAXB2.0 in JDK1.6

 
</p>            JAXBContext context = JAXBContext.newInstance(o.getClass());
 
            ByteArrayOutputStream bos = newByteArrayOutputStream();
            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.
<a name="_Toc290977345">1.1.2 Object class should have empty constructor

 
1.1.3 @XmlTransient to ignore some properties

Sometemporary data or some cycle reference relation.
 
Forexample, DDFNode.parentDDFNode.
 
1.1.4 @XmlJavaTypeAdapter

@XmlJavaTypeAdapteris used to adapter complex Object which is not recognized by JAXB into a simpleor customized Object.
1) XmlAdapter.marshal(BoundType):
a. Convert Object to anotherValueType 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 javaObject requested by business logical.
b. Used when XmlàObject
 
“List<String>tacs” instead of “Set tacs”
 
@XmlJavaTypeAdapteron field will lead to additional container tag. For example:
@XmlJavaTypeAdapter(FileNamesAdapter.class)
Map<String, String> profileMappings;
Willlead to XML like following:
            …
            < profileMappings >
                        <profile-mapping…/>
                        <!--your wrapper xmlelement-->;
            </ profileMappings >
But not:
            <profile-mapping …/>
 
It’sbetter to use List<> as collection implementation. And all the Object usesimple type.
 
Thereshould be dedicated Xml Java adapter for DDFNode, because:
1) DFPropterties is dedicatedcomplex element
2) Some elements have empty tag
3) List of child Nodes
4) …
 
1.1.5 @XmlType: Order of the Element: @XmlType(propOrder = {“parameterNames”})

Usefield name but not element name.
All thefields 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 extendsIdClass {
            …
}
@XmlSeeAlsocan be used to link the bund to its related subclasses. It will be used todefine InteriorDDFNode and LeafDDFNode. Because DDFTree use following definition:
    @XmlElement(name = "Node")
    private List<DDFNode> ddfNodes;
 
 
1.1.8 @XmlElementWrapper or not

@XmlElementWrapperis used to add a container tag for list,
Formodel/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 isno dedicated DFProperties bean object inside DDFNode.java.
Informationfor DFProperties are dynamic and has different value types.
 
UseXmlJavaTypeAdapter 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(newAccessTypeAdd());
                                    } else if(access.equalsIgnoreCase(AccessTypeCopy.ACCESS)) {
                                                accessTypes.add(newAccessTypeCopy());
                                    } else if(access.equalsIgnoreCase(AccessTypeDelete.ACCESS)) {
                                                accessTypes.add(newAccessTypeDelete());
                                    } else if(access.equalsIgnoreCase(AccessTypeExec.ACCESS)) {
                                                accessTypes.add(newAccessTypeExec());
                                    } else if(access.equalsIgnoreCase(AccessTypeReplace.ACCESS)) {
                                                accessTypes.add(newAccessTypeReplace());
                                    } else {
                                                accessTypes.add(newAccessTypeGet());
                                    }
                        }
 We can also use Map<accessTyeString, classNameString> to ignore many if...else....
 
DefineXmlElements 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 itwill generate the XML format like following:
        <AccessType>
            <Get/>
            <Add/>
            <Replace/>
        </AccessType>
 
页: [1]
查看完整版本: OXM: JAXB2.0 in JDK1.6