Jaxb解析xml准換為javabean


      先說下這個的背景吧,前些日子,有個以前的小同事說剛接觸webservice,想解析下xml,記得我學的時候還是dom4j,sax的解析方式,最近看別人的代碼用的jaxb的方式,覺得注解起來很簡練,所以就拿jaxb試着寫了一個,並一起總結一下,當做備忘錄吧。

      先看下xml的格式吧,如下

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mo version="1.0.0">
    <head>
        <businessType>PLANING_RECEIPTS</businessType>
    </head>
    <body>
        <planingReceiptsInfo>
            <manSign>
                <companyCode>發送方海關十位數編碼</companyCode>
                <businessNo>業務編碼</businessNo>
                <businessType>業務類型</businessType>
                <declareType>申報類型</declareType>
                <note>備注</note>
            </manSign>
            <manPlaningReceipts>
                <planingReceiptsId>計划入庫單編號</planingReceiptsId>
                <manualId>賬冊編號</manualId>
                <customsCode>關區代碼</customsCode>
                <companyCode>企業海關十位編碼</companyCode>
                <companyName>企業名稱</companyName>
                <grossWeight>毛重</grossWeight>
                <netWeight>凈重</netWeight>
                <amount>件數</amount>
                <wrapType>包裝種類</wrapType>
                <port>申報關區</port>
                <providerCodep>廠商編碼</providerCodep>
                <type>業務類別</type>
            </manPlaningReceipts>
            <manPlaningReceiptsDetailList>
                <manPlaningReceiptsDetail>
                    <planingReceiptsId>6</planingReceiptsId>
                    <sourceNo>8</sourceNo>
                    <itemNo>4</itemNo>
                    <itemType>5</itemType>
                    <goodsNo>3</goodsNo>
                    <declareAmount>2</declareAmount>
                    <totalPrice>9</totalPrice>
                    <price>7</price>
                    <countryCode>1</countryCode>
                </manPlaningReceiptsDetail>
                <manPlaningReceiptsDetail>
                    <planingReceiptsId>6</planingReceiptsId>
                    <sourceNo>8</sourceNo>
                    <itemNo>4</itemNo>
                    <itemType>5</itemType>
                    <goodsNo>3</goodsNo>
                    <declareAmount>2</declareAmount>
                    <totalPrice>9</totalPrice>
                    <price>7</price>
                    <countryCode>1</countryCode>
                </manPlaningReceiptsDetail>
            </manPlaningReceiptsDetailList>
        </planingReceiptsInfo>
    </body>
</mo>
View Code

   java解析類,如下

public class TestClass {
    public static void main(String[] args) {
        StringBuffer buffer  = null;
        JAXBContext jaxbContext;
        try {
            //讀入xml文件流
            InputStream is = new FileInputStream(new File("E:\\github\\myproject\\myweb\\src\\main\\resources\\test.xml"));
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            buffer = new StringBuffer();
            String line = "";
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }

            //加載映射bean類
            jaxbContext = JAXBContext.newInstance(BaseBean.class);
            //創建解析
            Unmarshaller um = jaxbContext.createUnmarshaller();
            StreamSource streamSource = new StreamSource(new StringReader(buffer.toString()));
            BaseBean root = (BaseBean) um.unmarshal(streamSource);
            System.out.println(root);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
View Code

 其中涉及的javabean相對多一點,就不在這貼了,一樣這種日常的東西還是會放到github下,當做自己的積累吧,有興趣可以down下來看看。

在這里說一下主要的注解,建議沒接觸過的拿着代碼對應着看:

1.XmlRootElement

    此注解是一個類級別注解,主要屬性為name,看名字也很清楚就是根節點的注解可以指定為根節點的名字

2.XmlType

    此注解主要屬性為propOrder,可以按指定的順序生成元素,且指定的順序必須為全部元素,否則是會報錯的

3.XmlElement

    此注解主要屬性為name,主要用於改變bean屬性與xml映射的名字,此注解的包為

javax.xml.bind.annotation,還有個包有相同的注解,用時需加注意。
lax屬性可能也需要,當設置lax為true時,可以把xsi:type, xmlns:xs等相關內容去掉

4.XmlAttribute

    此注解主要屬性為name,主要作用是可以把bean的屬性映射為xml

5.XmlAccessorType

    此注解用於指定由java對象生成xml文件時對java對象屬性的訪問方式

  • XmlAccessType.FIELD:java對象中的所有成員變量
  • XmlAccessType.PROPERTY:java對象中所有通過getter/setter方式訪問的成員變量
  • XmlAccessType.PUBLIC_MEMBER:java對象中所有的public訪問權限的成員變量和通過getter/setter方式訪問的成員變量
  • XmlAccessType.NONE:java對象的所有屬性都不映射為xml的元素

6.XmlAccessorOrder

   用於對java對象生成的xml元素進行排序。其value屬性,它有兩個屬性值:

    XmlAccessOrder.ALPHABETICAL:對生成的xml元素按字母書序排序

    XmlAccessOrder.UNDEFINED:不排序

7.XmlTransient

   用於標示在由java對象映射xml時,忽略此屬性

8.XmlElementWrapper

    表示生成一個包裝 XML 表示形式的包裝器元素。 此元素主要用於生成一個包裝集合的包裝器 XML 元素。
注:@XmlElementWrapper僅允許出現在集合屬性上。

9.XmlJavaTypeAdapter

    常用在轉換比較復雜的對象時,用此注解時,需要自己寫一個adapter類繼承XmlAdapter抽象類,並實現里面的方法

最后把測試上述注解的代碼放到這,可以跑一下,就全清楚了,里面還接了放泛型的相關內容

@XmlRootElement(name = "address")
//@XmlType(propOrder = {"name", "code"})
//@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(value = XmlAccessOrder.ALPHABETICAL)
public class TestAddress<T> {

/** code */
private int code;

/** company */
private String name;

/** des */
private String des;

private String xxxx;

private Date nowDate;

private T body;
@XmlElementWrapper(name = "listTest")
@XmlElement(name = "list123")
public List<String> getList() {
return list;
}

public void setList(List<String> list) {
this.list = list;
}

private List<String> list;
/**
* @return 獲取 code屬性值
*/
public int getCode() {
return code;
}

/**
* @param code 設置 code 屬性值為參數值 code
*/
@XmlElement(name = "code1")
public void setCode(int code) {
this.code = code;
}

/**
* @return 獲取 name屬性值
*/
public String getName() {
return name;
}

/**
* @param name 設置 name 屬性值為參數值 name
*/
public void setName(String name) {
this.name = name;
}

@XmlAttribute(name = "desProperty")
public String getDes() {
return des;
}

public void setDes(String des) {
this.des = des;
}

@XmlTransient
public String getXxxx() {
return xxxx;
}

public void setXxxx(String xxxx) {
this.xxxx = xxxx;
}

public Date getNowDate() {
return nowDate;
}

@XmlJavaTypeAdapter(value = DateAdapter.class)
public void setNowDate(Date nowDate) {
this.nowDate = nowDate;
}

public T getBody() {
return body;
}

@XmlAnyElement(lax=true)
public void setBody(T t) {
this.body = t;
}

@Override
public String toString() {
return "TestAddress{" +
"code=" + code +
", name='" + name + '\'' +
", des='" + des + '\'' +
", xxxx='" + xxxx + '\'' +
", nowDate=" + nowDate +
", body=" + body +
", list=" + list +
'}';
}
}
@XmlRootElement(name = "body")
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbBean {
    private String bean1;
    private String bean2;

    public String getBean1() {
        return bean1;
    }

    public void setBean1(String bean1) {
        this.bean1 = bean1;
    }

    public String getBean2() {
        return bean2;
    }

    public void setBean2(String bean2) {
        this.bean2 = bean2;
    }

    @Override
    public String toString() {
        return "JaxbBean{" +
                "bean1='" + bean1 + '\'' +
                ", bean2='" + bean2 + '\'' +
                '}';
    }
}
public class OXMapper {

    /** Marshaller */
    private Marshaller marshaller;

    /** Unmarshaller */
    private Unmarshaller unmarshaller;

    /**
     * @return 獲取 marshaller屬性值
     */
    public Marshaller getMarshaller() {
        return marshaller;
    }

    /**
     * @param marshaller 設置 marshaller 屬性值為參數值 marshaller
     */
    public void setMarshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }

    /**
     * @return 獲取 unmarshaller屬性值
     */
    public Unmarshaller getUnmarshaller() {
        return unmarshaller;
    }

    /**
     * @param unmarshaller 設置 unmarshaller 屬性值為參數值 unmarshaller
     */
    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    /**
     * 將對象轉換輸出為xml文件
     *
     * @param object object 對象
     * @param filename filename 文件名
     * @throws IOException IOException IO異常
     */
    public void writeObjectToXml(Object object, String filename) throws IOException {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filename);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(object, new StreamResult(fos));
        } catch (JAXBException e) {
            //LOG.error("Xml-Serialization failed due to an XmlMappingException.", e);
        } catch (IOException e) {
            //LOG.error("Xml-Serialization failed due to an IOException.", e);
        } finally {
            if (fos != null) {
                fos.close();
            }
        }
    }

    /**
     * 將xml文件轉換成java對象
     *
     * @param filename filename 文件名稱
     * @return Object 轉換后的java對象
     * @throws IOException IOException IO異常
     * @throws JAXBException JAXBException JAXB異常
     */
    public Object readObjectFromXml(String filename) throws IOException, JAXBException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filename);
            return unmarshaller.unmarshal(new StreamSource(fis));
        } catch (IOException e) {
           // LOG.error("Xml-Deserialization failed due to an IOException.", e);
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
        return null;
    }

    /**
     * 測試用例
     *
     * @param args 傳入參數
     * @throws IOException IOException
     * @throws JAXBException JAXBException
     */
    public static void main(String[] args) throws IOException, JAXBException {
        JaxbBean jaxbBean = new JaxbBean();
        jaxbBean.setBean1("124");
        jaxbBean.setBean2("456");
//

        TestAddress<JaxbBean> address = new TestAddress<JaxbBean>();
        address.setCode(58888);
        address.setName("深圳市福田區蓮花路2075號香麗大廈首層");
        address.setDes("測試屬性");
        address.setXxxx("xxxx");
        address.setNowDate(new Date());
        List<String> list1 = new ArrayList<String>();
        list1.add("test1");
        list1.add("test2");
        address.setList(list1);
        address.setBody(jaxbBean);

        JAXBContext objJaxbContext = JAXBContext.newInstance(address.getClass(), jaxbBean.getClass());
        Marshaller objMarshaller = objJaxbContext.createMarshaller();
        OXMapper oxMapper = new OXMapper();
        oxMapper.setMarshaller(objMarshaller);
        oxMapper.writeObjectToXml(address, "address.xml");
        System.out.println("bean轉xml結束");

        Unmarshaller objUnmarshaller = objJaxbContext.createUnmarshaller();

        oxMapper.setUnmarshaller(objUnmarshaller);
        TestAddress objAddress = (TestAddress) oxMapper.readObjectFromXml("address.xml");
        System.out.println(objAddress);
        //System.out.println(ReflectionToStringBuilder.toString(objAddress, ToStringStyle.MULTI_LINE_STYLE));
    }
}

 

參考

1.http://my.oschina.net/zzx0421/blog/98186

2.http://www.aiuxian.com/article/p-3149775.html

3.http://suo.iteye.com/blog/1233603


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM