38.2. XML 스키마의 Java 클래스 지정

38.2.1. 개요

기본적으로 XML 스키마 유형은 Java 기본 유형에 매핑됩니다. XML 스키마와 Java 간의 가장 논리적인 매핑이지만 애플리케이션 개발자의 요구 사항을 항상 충족하는 것은 아닙니다. XML 스키마 기본 유형을 추가 정보를 저장할 수 있는 Java 클래스에 매핑하거나 XML 기본 유형을 간단한 형식 대체를 허용하는 클래스에 매핑해야 할 수 있습니다.

CryostatB javaType 사용자 지정 요소를 사용하면 XML 스키마 기본 유형과 Java 기본 유형 간의 매핑을 사용자 지정할 수 있습니다. 글로벌 수준 및 개별 인스턴스 수준에서 매핑을 사용자 지정하는 데 사용할 수 있습니다. javaType 요소를 간단한 형식 정의의 일부로 사용하거나 복잡한 형식 정의의 일부로 사용할 수 있습니다.

javaType 사용자 지정 요소를 사용하는 경우 기본 유형의 XML 표현을 대상 Java 클래스로 변환하기 위한 메서드를 지정해야 합니다. 일부 매핑에는 기본 변환 방법이 있습니다. 기본 매핑이 없는 인스턴스의 경우 Apache CXF는 CryostatB 메서드를 제공하여 필요한 메서드를 쉽게 개발할 수 있습니다.

38.2.2. 구문

javaType 사용자 지정 요소는 표 38.1. “XML 스키마 유형에 대한 Java 클래스 생성 사용자 지정을 위한 속성” 에 설명된 대로 4개의 속성을 사용합니다.

표 38.1. XML 스키마 유형에 대한 Java 클래스 생성 사용자 지정을 위한 속성

속성필수 항목설명

name

제공됨

XML Schema 기본 유형이 매핑되는 Java 클래스의 이름을 지정합니다. 유효한 Java 클래스 이름 또는 Java 기본 유형의 이름이어야 합니다. 이 클래스가 존재하고 애플리케이션에서 액세스할 수 있는지 확인해야 합니다. 코드 생성기는 이 클래스를 확인하지 않습니다.

xmlType

없음

사용자 지정되는 XML Schema 기본 유형을 지정합니다. 이 속성은 javaType 요소가 globalBindings 요소의 자식으로 사용되는 경우에만 사용됩니다.

parseMethod

없음

데이터의 문자열 기반 XML 표현을 Java 클래스의 인스턴스로 구문 분석하는 방법을 지정합니다. 자세한 내용은 “변환기 지정” 에서 참조하십시오.

printMethod

없음

Java 개체를 데이터의 문자열 기반 XML 표현으로 변환하는 방법을 지정합니다. 자세한 내용은 “변환기 지정” 에서 참조하십시오.

javaType 사용자 지정 요소는 다음 세 가지 방법으로 사용할 수 있습니다.

  • XML 스키마 기본 유형의 모든 인스턴스를 수정하려면 javaType 요소는 globalBindings 사용자 지정 요소의 자식으로 사용할 때 스키마 문서의 XML Schema 유형의 모든 인스턴스를 수정합니다. 이러한 방식으로 사용될 때는 수정되는 XML 스키마 기본 형식을 식별하는 xmlType 속성 값을 지정해야 합니다.

    예 38.7. “글로벌 우선순위 유형 사용자 정의” 는 스키마의 모든 xsd:short 인스턴스에 java.lang.Integer 를 사용하도록 코드 생성기를 지시하는 인라인 글로벌 사용자 지정을 보여줍니다.

    예 38.7. 글로벌 우선순위 유형 사용자 정의

    <schema targetNamespace="http://widget.com/types/widgetTypes"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
            jaxb:version="2.0">
      <annotation>
        <appinfo>
          <jaxb:globalBindings ...>
            <jaxb:javaType name="java.lang.Integer"
                           xmlType="xsd:short" />
          </globalBindings
        </appinfo>
      </annotation>
      ...
    </schema>
  • 간단한 유형 정의를 수정하려면 javaType 요소는 명명된 단순 형식 정의에 적용할 때 XML simple 형식의 모든 인스턴스에 대해 생성된 클래스를 수정합니다. javaType 요소를 사용하여 간단한 유형 정의를 수정하는 경우 xmlType 특성을 사용하지 마십시오.

    예 38.8. “단순 유형 사용자 지정을 위한 바인딩 파일” zipCode 라는 간단한 유형의 생성을 수정하는 외부 바인딩 파일을 표시합니다.

    예 38.8. 단순 유형 사용자 지정을 위한 바인딩 파일

    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   jaxb:version="2.0">
      <jaxb:bindings wsdlLocation="widgets.wsdl">
        <jaxb:bindings node="xsd:simpleType[@name='zipCode']">
            <jaxb:javaType name="com.widgetVendor.widgetTypes.zipCodeType"
                           parseMethod="com.widgetVendor.widgetTypes.support.parseZipCode"
                           printMethod="com.widgetVendor.widgetTypes.support.printZipCode" />
        </jaxb:bindings>
      </jaxb:bindings>
    <jaxb:bindings>
  • 복잡한 유형 정의의 요소 또는 특성을 수정하기 위해 javaType 은 CryostatB 속성 사용자 지정의 일부로 포함하여 복잡한 유형 정의의 개별 부분에 적용할 수 있습니다. javaType 요소는 속성의 baseType 요소에 자식으로 배치됩니다. javaType 요소를 사용하여 복잡한 유형 정의의 특정 부분을 수정하는 경우 xmlType 특성을 사용하지 마십시오.

    예 38.9. “복잡한 유형의 요소 사용자 지정을 위한 바인딩 파일” 복합 형식의 요소를 수정하는 바인딩 파일을 표시합니다.Shows a binding file that modifies an element of a complex type.

    예 38.9. 복잡한 유형의 요소 사용자 지정을 위한 바인딩 파일

    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   jaxb:version="2.0">
      <jaxb:bindings schemaLocation="enumMap.xsd">
        <jaxb:bindings node="xsd:ComplexType[@name='widgetOrderInfo']">
          <jaxb:bindings node="xsd:element[@name='cost']">
            <jaxb:property>
              <jaxb:baseType>
                <jaxb:javaType name="com.widgetVendor.widgetTypes.costType"
                                parseMethod="parseCost"
                                printMethod="printCost" >
              </jaxb:baseType>
            </jaxb:property>
          </jaxb:bindings>
        </jaxb:bindings>
      </jaxb:bindings>
    <jaxb:bindings>

    baseType 요소 사용에 대한 자세한 내용은 38.6절. “요소 또는 속성의 기본 유형 지정” 을 참조하십시오.

38.2.3. 변환기 지정

Apache CXF는 XML 스키마 기본 유형을 임의의 Java 클래스로 변환할 수 없습니다. javaType 요소를 사용하여 XML 스키마 기본 유형의 매핑을 사용자 지정할 때 코드 생성기는 사용자 지정된 XML 스키마 기본 유형을 마샬링하고 unmarshal하는 데 사용되는 어댑터 클래스를 만듭니다. 샘플 어댑터 클래스는 예 38.10. “CryostatB 어댑터 클래스” 에 표시됩니다.

예 38.10. CryostatB 어댑터 클래스

public class Adapter1 extends XmlAdapter<String, javaType>
{
  public javaType unmarshal(String value)
  {
    return(parseMethod(value));
  }

  public String marshal(javaType value)
  {
    return(printMethod(value));
  }
}

parseMethodprintMethod 는 해당 parseMethod 속성 및 printMethod 속성 값으로 교체됩니다. 값은 유효한 Java 메서드를 식별해야 합니다. 다음 두 가지 방법 중 하나로 메서드의 이름을 지정할 수 있습니다.

  • 패키지 이름 .ClassName. methodName 형식의 정규화된 Java메서드 이름
  • methodName 형식의 간단한 메서드 이름

    간단한 메서드 이름만 제공하는 경우 코드 생성기는 이 메서드가 javaType 요소의 name 특성에 지정된 클래스에 있다고 가정합니다.

중요

코드 생성기는 구문 분석 또는 인쇄 메서드를 생성하지 않습니다. 이를 제공할 책임이 있습니다. 구문 분석 및 인쇄 방법 개발에 대한 자세한 내용은 “변환기 구현” 에서 참조하십시오.

parseMethod 특성에 대한 값이 제공되지 않으면 코드 생성기는 name 특성에 지정된 Java 클래스에 첫 번째 매개 변수가 Java String 개체인 생성자가 있다고 가정합니다. 생성된 어댑터의 unmarshal() 메서드는 가정된 생성자를 사용하여 Java 개체를 XML 데이터로 채웁니다.

printMethod 속성 값을 제공하지 않으면 코드 생성기는 name 특성에 지정된 Java 클래스에 toString() 메서드가 있다고 가정합니다. 생성된 어댑터의 marshal() 메서드는 가정된 toString() 메서드를 사용하여 Java 개체를 XML 데이터로 변환합니다.

javaType 요소의 name 속성이 Java 기본 유형 또는 Java 기본의 래퍼 유형 중 하나를 지정하는 경우 코드 생성기는 기본 변환기를 사용합니다. 기본 변환기에 대한 자세한 내용은 “기본 기본 유형 변환기” 을 참조하십시오.

38.2.4. 생성된 항목

“변환기 지정” 에서 언급했듯이 javaType 사용자 지정 요소를 사용하면 XML 스키마 기본 유형의 각 사용자 지정에 대해 하나의 어댑터 클래스 생성이 트리거됩니다. 어댑터는 패턴 AdapterN 을 사용하여 순서대로 지정됩니다. 두 개의 기본 유형 사용자 지정을 지정하면 코드 생성기는 Adapter1Adapter2 의 두 가지 어댑터 클래스를 만듭니다.

XML 스키마 구성에 대해 생성된 코드는 영향을 받는 XML 스키마 구성이 전역적으로 정의된 요소인지 아니면 복잡한 유형의 일부로 정의되었는지에 따라 달라집니다.

XML 스키마 구성이 전역적으로 정의된 요소인 경우 유형에 대해 생성된 개체 팩토리 메서드는 다음과 같이 기본 메서드에서 수정됩니다.

  • 메서드는 @ CryostatJavaTypeAdapter 주석과 함께 데코레이터됩니다.

    주석은 이 요소의 인스턴스를 처리할 때 사용할 어댑터 클래스를 런타임에 지시합니다. adapter 클래스는 클래스 오브젝트로 지정됩니다.

  • 기본 유형은 javaType 요소의 name 속성으로 지정된 클래스로 교체됩니다.

예 38.11. “글로벌 요소를 위한 사용자 지정 오브젝트 Cryostat 방법” 예 38.7. “글로벌 우선순위 유형 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 표시합니다.

예 38.11. 글로벌 요소를 위한 사용자 지정 오브젝트 Cryostat 방법

 @XmlElementDecl(namespace = "http://widgetVendor.com/types/widgetTypes", name = "shorty")
 @XmlJavaTypeAdapter(org.w3._2001.xmlschema.Adapter1.class)
 public JAXBElement<Integer> createShorty(Integer value) {
     return new JAXBElement<Integer>(_Shorty_QNAME, Integer.class, null, value);
 }

XML 스키마 구성이 복잡한 유형의 일부로 정의되면 생성된 Java 속성은 다음과 같이 수정됩니다.

  • 속성은 @ CryostatJavaTypeAdapter 주석과 함께 데코레이터됩니다.

    주석은 이 요소의 인스턴스를 처리할 때 사용할 어댑터 클래스를 런타임에 지시합니다. adapter 클래스는 클래스 오브젝트로 지정됩니다.

  • 속성의 @ Cryostat에는 type 속성이 포함되어 있습니다.

    type 속성의 값은 생성된 오브젝트의 기본 유형을 나타내는 클래스 오브젝트입니다. XML 스키마 기본 유형의 경우 클래스는 String 입니다.

  • 속성은 @ CryostatSchemaType 주석으로 데코레이팅됩니다.

    이 주석은 구문의 XML 스키마 기본 유형을 식별합니다.

  • 기본 유형은 javaType 요소의 name 속성으로 지정된 클래스로 교체됩니다.

예 38.12. “사용자 정의 복잡한 유형” 예 38.7. “글로벌 우선순위 유형 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 표시합니다.

예 38.12. 사용자 정의 복잡한 유형

public class NumInventory {

    @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1.class) @XmlSchemaType(name = "short") protected Integer numLeft;
    @XmlElement(required = true)
    protected String size;

    public Integer getNumLeft() {
        return numLeft;
    }

    public void setNumLeft(Integer value) {
        this.numLeft = value;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String value) {
        this.size = value;
    }

}

38.2.5. 변환기 구현

Apache CXF 런타임은 parseMethod 속성 및 printMethod 특성에 지정된 메서드를 호출해야 한다는 점을 제외하고 javaType 요소에서 지정한 Java 클래스로 XML 기본 유형을 변환하는 방법을 알 수 없습니다. 런타임 호출을 수행하는 메서드의 구현을 제공해야 합니다. 구현된 메서드는 XML 기본 유형의 사전 구조로 작업할 수 있어야 합니다.

데이터 변환 방법 구현을 단순화하기 위해 Apache CXF는 javax.xml.bind.DatatypeConverter 클래스를 제공합니다. 이 클래스는 모든 XML 스키마 기본 유형을 구문 분석하고 출력하기 위한 메서드를 제공합니다. 구문 분석 메서드는 XML 데이터의 문자열 표현을 사용하고 표 34.1. “XML Schema Primitive Type to Java Native Type Mapping” 에 정의된 기본 유형의 인스턴스를 반환합니다. 출력 메서드는 기본 유형의 인스턴스를 사용하고 XML 데이터의 문자열 표현을 반환합니다.

DatatypeConverter 클래스에 대한 Java 문서는 https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/DatatypeConverter.html 에서 확인할 수 있습니다.

38.2.6. 기본 기본 유형 변환기

Java 기본 유형 또는 Java 기본 유형 Wrapper 클래스 중 하나를 지정할 때 javaType 요소의 name 속성에서 parseMethod 속성 또는 printMethod 특성에 대한 값을 지정할 필요가 없습니다. Apache CXF 런타임은 값이 제공되지 않는 경우 기본 변환기를 대체합니다.

기본 데이터 변환기는 CryostatB DatatypeConverter 클래스를 사용하여 XML 데이터를 구문 분석합니다. 기본 변환기는 변환 작업을 수행하는 데 필요한 모든 유형을 캐스팅합니다.