Hello JAXB2 and JavaSE6

0

源起

幾個專案用過 XMLBeans,還不錯用,之前評估過 JAXB 1.0 版本,有兩個問題, 一是 XML Schema 支援有點問題,一是 JAXB 當時有商業授權等議題。

這些專案是採 XML Schema 為主的做法,也就是需要先由客戶端決定商業領域的語法, 交付寫好的 schema,那時 JAXB 1 沒辦法很方便的foo.xsd 轉 foo.java, 而 foo.xsd 一直改到後期會越來越複雜,一堆的 complex type,所以那時找到能 符合專案 schema 與授權的方案是 BEA 釋出的 Apache XMLBeans。

不過時過境遷,現在 JAXB 2 授權也改了,支援 XML schema 應該也 比較好,同時 JavaSE6 已經內建支援,於是來玩看看。

http://download.java.net/jdk6/docs/technotes/guides/xml/jaxb/index.html

scheam-first or code-first

如果先寫 schema 的話,需要使用 xjc,就 eclipse 來說,使用 ant 比較方便。 不過 com.sun.tools.xjc.XJCTask 並不存在 JRE 中,需要下載 jaxb-xjc.jar 來用。

https://jaxb.dev.java.net/nonav/2.0.2/docs/xjcTask.html

https://jaxb.dev.java.net/

用 xjc 產生 java 碼後,就可以開始用。

ProjectType pj = new ProjectType();
...[SKIP]
ObjectFactory objFactory = new ObjectFactory();
JAXBElement<ProjectType> je = objFactory.createProject(pj);

JAXBContext jc = JAXBContext.newInstance(ProjectType.class);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

簡單 marshaller.marshal(jaxbElement, System.out) 的結果。

<ns2:project xmlns:ns2="http://config.service.haha/ns/project">
    <profile>
        <name>FOO PROJECT</name>
    </profile>
</ns2:project>

更換 ns2

指定預設或是更動命名空間的 prefix 並不在 JAXB2 的規格 (JSR-222 spec) 中, 所以 JAVA6 平台無法提供這類的 marshaller 機制,要用 JAXB2 RI 才可以, 因為有的 schema 的 prefix 名稱是定死的,不支援這個會比較麻煩。

//  RI 才有支援,需要 jaxb-impl.jar,JAVA6  不包含
marshller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
  new NamespacePrefixMapper() {
    @Override
    public String getPreferredPrefix(String nsuri,
               String suggestion, boolean requirePrefix) {
        // 無法調成 default 只能改掉。用 "" 無效 ?
        if ("http://config.service.haha/ns/project".equals(nsuri))
            return "pj";
        return suggestion;
      }
    });

結果輸出

<pj:project xmlns:pj="http://config.service.haha/ns/project">
    <profile>
        <name>FOO PROJECT</name>
    </profile>
</pj:project>

取部份 XML 輸出

之前用 XMLBeans 都用複製 copy 模式建立另一個文件來修改取出需要的部份, JAXB 似乎沒有這類方式,需要建立兩個物件複製。

haha.remix.jaxb

基本上就是轉包 jaxb-api.jar, jaxb-impl.jar, jsr173_1.0_api.jar 供 OSGi 平台使用, JAVA6 雖然有支援 JAXB2,但是需要 com.sun.xml.bind.namespacePrefixMapper 的情況下, 還是要使用附加的 jaxb-impl.jar。

另外使用 haha.remix.jaxb 讓 JAVA5 也一樣可以用。

JAVA6

根據 Java 6 Leads Out of the Box Server Performance 的說法,這個快上很多的出場預設性能蠻吸引人的。

觀察

  1. 因為 JAXB 已經是個標準,關於 JAXB 的用法還要再深入觀察。
  2. 個人目前用起來 XMLBeans 比較直覺,也有可能是用習慣的關係。
  3. 簡單的綁定, JAVA 6 是個不錯的現成平台,如果要更細部的支援,無可避免還是要加 jar 到平台上,這時 JAXB2 RI 或是 XMLBeans 就看哪個用的順手,功能也都可以提供為主。

Comments

(leave url/email »)

   Preview comment