読者です 読者をやめる 読者になる 読者になる

ひこぽんのーと

覚書と雑記です。

JavaEE 7をやってみよう。 JAX-RS その6

その5の続き。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="result" type="catalog"/>

  <xs:complexType name="catalog">
    <xs:sequence>
      <xs:element name="shipList" type="warShip" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="warShip">
    <xs:sequence>
      <xs:element name="type" type="xs:string" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

これを書き換えるのだけど、
XMLスキーマの細かい書き方はよくわからない。
仕様については検索すれば詳しいページはいくらでもある、のだろうが、
ここはインスタントでいく。

まず、内容を見る限りComplexTypeとあるところが型宣言のようだ。
CatalogとWarShipの2つ。これはJavaクラスと一致する。
ここにあるelement属性をよく見ると、
"result", "shipList", "type", "name"の4種と、
出力されるタグの種類が一致していることがわかる。

ということは。。。。
element属性にwarShipListとwarShipを追加してやればよいのではないか?
と思いたち、そんな具合に直してみることにする。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="result" type="catalog"/>

  <xs:complexType name="catalog">
    <xs:sequence>
      <xs:element name="warShipList" type="warShipList" minOccurs="1" maxOccurs="1" nillable="false" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="warShipList">
    <xs:sequence>
      <xs:element name="warShip" type="warShip" minOccurs="0"  maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="warShip">
    <xs:sequence>
      <xs:element name="type" type="xs:string" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

変更点は、warShipListの型宣言の追加、
Catalogのelement名をwarShipListに変更し、型をwarShipList型としたこと。
ついでにNULL不許可とか最小出現数、最大出現数なんかも増やした。

これを元にJavaクラスを作ってみる。
スキーマファイルは新規のウィザードから作ったが、
xsdファイルからJavaクラスの生成は、コンテキストメニューからでも行ける。
xsdファイルを選択し、コンテキストメニューから「生成」→「JAXB Classes」を選ぶ。

1. 保存先のプロジェクトを選択。
今回はJAXBプロジェクトを選んだ。
f:id:nagamitsu1976:20150821162937p:plain
2. 出力パッケージの選択
xsd生成元のJavaクラスと同じ場所にした。
f:id:nagamitsu1976:20150821163055p:plain
3. オプション選択。
詳しくは調査が必要なので、今回はデフォルトのままにした。
f:id:nagamitsu1976:20150821163224p:plain
f:id:nagamitsu1976:20150821163302p:plain
4. 生成
完了ボタンを押すと生成が始まる。
今回、既存のクラスがすでにあったため警告が出るが、上書きで問題ないため「はい」を押す。
f:id:nagamitsu1976:20150821163318p:plain

Javaリソースを見てみるとクラスが書き換わっているのがわかる。

Catalogクラス
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.21 at 04:28:09 PM JST 
//


package jaxrs.bean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for catalog complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="catalog">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="warShipList" type="{}warShipList"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "catalog", propOrder = {
    "warShipList"
})
public class Catalog {

    @XmlElement(required = true)
    protected WarShipList warShipList;

    /**
     * Gets the value of the warShipList property.
     * 
     * @return
     *     possible object is
     *     {@link WarShipList }
     *     
     */
    public WarShipList getWarShipList() {
        return warShipList;
    }

    /**
     * Sets the value of the warShipList property.
     * 
     * @param value
     *     allowed object is
     *     {@link WarShipList }
     *     
     */
    public void setWarShipList(WarShipList value) {
        this.warShipList = value;
    }

}
WarShipListクラス
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.21 at 04:28:09 PM JST 
//


package jaxrs.bean;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for warShipList complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="warShipList">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="warShip" type="{}warShip" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "warShipList", propOrder = {
    "warShip"
})
public class WarShipList {

    protected List<WarShip> warShip;

    /**
     * Gets the value of the warShip property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the warShip property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getWarShip().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link WarShip }
     * 
     * 
     */
    public List<WarShip> getWarShip() {
        if (warShip == null) {
            warShip = new ArrayList<WarShip>();
        }
        return this.warShip;
    }

}
||

:WarShipクラス:
>|java|
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.21 at 04:28:09 PM JST 
//


package jaxrs.bean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for warShip complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="warShip">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "warShip", propOrder = {
    "type",
    "name"
})
public class WarShip {

    protected String type;
    protected String name;

    /**
     * Gets the value of the type property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getType() {
        return type;
    }

    /**
     * Sets the value of the type property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setType(String value) {
        this.type = value;
    }

    /**
     * Gets the value of the name property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the value of the name property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setName(String value) {
        this.name = value;
    }

}
ObjectFactoryクラス
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2015.08.21 at 04:28:09 PM JST 
//


package jaxrs.bean;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


/**
 * This object contains factory methods for each 
 * Java content interface and Java element interface 
 * generated in the jaxrs.bean package. 
 * <p>An ObjectFactory allows you to programatically 
 * construct new instances of the Java representation 
 * for XML content. The Java representation of XML 
 * content can consist of schema derived interfaces 
 * and classes representing the binding of schema 
 * type definitions, element declarations and model 
 * groups.  Factory methods for each of these are 
 * provided in this class.
 * 
 */
@XmlRegistry
public class ObjectFactory {

    private final static QName _Result_QNAME = new QName("", "result");

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: jaxrs.bean
     * 
     */
    public ObjectFactory() {
    }

    /**
     * Create an instance of {@link Catalog }
     * 
     */
    public Catalog createCatalog() {
        return new Catalog();
    }

    /**
     * Create an instance of {@link WarShipList }
     * 
     */
    public WarShipList createWarShipList() {
        return new WarShipList();
    }

    /**
     * Create an instance of {@link WarShip }
     * 
     */
    public WarShip createWarShip() {
        return new WarShip();
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link Catalog }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "", name = "result")
    public JAXBElement<Catalog> createResult(Catalog value) {
        return new JAXBElement<Catalog>(_Result_QNAME, Catalog.class, null, value);
    }

}

自動生成されたクラスを見るとXML系のアノテーションの付け方が異なることがわかる。
@XmlAccessorTypeアノテーションだとか、@XmlElementの付ける位置だとか、色々。
これらを元にアノテーションについて調査をすれば、
もっと詳しい仕様が理解できると思う。
が、それはまた別の機会にするとして、
自動生成したクラスをREST用のプロジェクトにコピーして、
出力結果を確認してみることにする。

といったところで、次回に続く。