JAX-Bの例

5672 ワード

wsgenツールは、JavaとXMLの間のタイプ変換を実現するためにJAX-B関連のAPIパッケージを下位層で使用しているので、JavaとXMLの間でどのように変換されているかをJAX-Bの例で理解してみましょう.Personクラス(人)とSkierクラス(スキー選手)を作成し、JavaからXMLへのバインドを説明するために、各クラス定義の先頭に個別の注釈があります.Personクラスは@XmlTypeとして注記され、Skierクラスは@XmlRootElementとして注記される.次の例を示します.
Person.javaクラス:
package ch04.ts;

import javax.xml.bind.annotation.XmlType;

@XmlType
public class Person {

	private String name;
	private int age;
	private String gender;
	
	public  Person() {}
	public Person(String name,int age,String gender){
		setName(name);
		setAge(age);
		setGender(gender);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
}

Skier.javaクラス:
package ch04.ts;

import java.util.Collection;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Skier {

	private Person person;
	private String national_team;
	private Collection<String> major_achievements;
	
	public Skier(){}
	public Skier(Person person,String national_team,
	    Collection<String> major_achievements){
		setPerson(person);
		setNational_team(national_team);
		setMajor_achievements(major_achievements);
	}
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	public String getNational_team() {
		return national_team;
	}
	public void setNational_team(String national_team) {
		this.national_team = national_team;
	}
	public Collection<String> getMajor_achievements() {
		return major_achievements;
	}
	public void setMajor_achievements(Collection<String> major_achievements) {
		this.major_achievements = major_achievements;
	}
}

@XmlTypeと@XmlRootElement注釈は、Skierオブジェクトの符号化(Marshaling)に関与している.符号化とは、メモリオブジェクト(例えばSkierオブジェクト)をXMLドキュメント形式で処理するプロセスであるため、例えば、ネットワーク伝送を利用した符号化は、受信側で復号(Unmarshal)処理され得る.通常の使用では、符号化と復号化の間に大きな違いはなく、シーケンス化/逆シーケンス化の間の違いとほぼ同等である.JAX-Bは、メモリ内のjavaオブジェクトをXMLドキュメントにシーケンス化するとともに、XMLドキュメントをメモリ内のjavaオブジェクトに逆シーケンス化することをサポートします.
Personクラスでは、注記@XmlTypeは、JAX-Bがjavaタイプに対応するXMLモードタイプを生成すべきであることを示しています.Skierクラスでは、注記@XmlRootElementは、JAX-BがJavaクラスのXMLドキュメント(最外層またはルート要素)を生成する必要があることを示しています.そこで、最終的に生成されたXMLドキュメントの最外層のルート要素は、skierを記述するために使用され、skierにネストされたサブ要素がpersonを記述するために使用される.
skierを符号化および復号化する例Marshal.java:
package ch04.ts;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Marshal {
	private static final String file_name = "bd.xml";
	public static void main(String[] args) {
		new Marshal().run_example();
	}
	private void run_example(){
		try {
			//  JAXB     
			JAXBContext ctx = JAXBContext.newInstance(Skier.class);
			//     
			Marshaller m = ctx.createMarshaller();
			//        
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			Skier skier = createSkier();
			//      XML        
			m.marshal(skier, System.out);
			
			FileOutputStream out = new FileOutputStream(file_name);
			//      XML       
			m.marshal(skier, out);
			out.close();
			
			//     
			Unmarshaller u = ctx.createUnmarshaller();
			//      XML       java  
			Skier bd_clone = (Skier) u.unmarshal(new File(file_name));
			System.out.println();
			//       XML       
			m.marshal(bd_clone, System.out);
		} catch (JAXBException e1) {
			e1.printStackTrace();
		} catch (FileNotFoundException e2){
			e2.printStackTrace();
		} catch (IOException e3){
			e3.printStackTrace();
		}
	}
	private Skier createSkier(){
		Person bd = new Person("Bjoern Daehlie",41,"Male");
		List<String> list = new ArrayList<String>();
		list.add("12 Olympic Medals");
		list.add("9 World Championships");
		list.add("Winningest Winter Olympian");
		list.add("Greatest Nordic Skier");
		return new Skier(bd,"Norway",list);
		
	}
}

デフォルトでは、JAX-Bエンコーディングは標準のJavaおよびJavaBeanネーミング仕様に従います.たとえばSkierクラスのXMLタグ名はskier,PersonクラスのXMLタグ名はpersonである.Skierオブジェクトとカプセル化されたPersonオブジェクトについて、JavaBeanスタイルのgetメソッドを呼び出してオブジェクトの関連状態情報を取得し、生成するXMLドキュメントに入力します.
JavaBeanネーミング仕様に従ったクラスを符号化および復号する場合、注釈を追加したメソッドを書き換えることができます.ただし、wsgenによって生成されたjavaクラスはJavaBeanネーミングルールに従っていません.次の例を参照してください.
@XmlRootElement(name = "getTimeAsElapsedResponse",namespace = "http://ts.ch02/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getTimeAsElapsedResponse",namespace = "http://ts.ch02/")
public class GetTimeAsElapsedResponse{
    @XmlElement(name = "return", namespace = "")
    private long _return;
    public long get_return(){
        return this._return;
    }
    public void set_return(long _return){
        this._return = _return;
    }
}

注意@XmlAccessorType(XmlAccessType.FIELD)という注記は、フィールド名「_return」がJavaBeanネーミング仕様に従って対応するgetter/setterメソッドペアを定義していないことを示しています.
また、注記プロパティの他の値を設定することで、Skierクラスの注記宣言が次のように変更された場合、デフォルトの命名規則を上書きできます.
@XmlRootElement(name = "NordicSkier")

生成されたXMLドキュメントは次のようになります.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<NordicSkier>
    .....

注意:JAX-B復号化では、各クラスがオブジェクトを構築するために公開された無パラメトリック構造方法を持つ必要があります.