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

38.2.1. 개요

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

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

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

38.2.2. 구문

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

표 38.1. XML 스키마 유형에 대한 Java 클래스 생성을 사용자 정의하는 특성

속성필수 항목설명

name

있음

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

xmlType

없음

사용자 지정할 XML 스키마 기본 유형을 지정합니다.Specifies the XML Schema primitive type that is being customized. 이 특성은 javaType 요소가 globalBindings 요소의 자식으로 사용되는 경우에만 사용됩니다.

parseMethod

없음

데이터의 문자열 기반 XML 표현을 Java 클래스의 인스턴스로 구문 분석하는 메서드를 지정합니다.Specifies the method responsible for parsing the string-based XML representation of the data into an instance of the Java class. 자세한 내용은 “변환기 지정” 에서 참조하십시오.

printMethod

없음

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

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

  • XML 스키마 기본 형식의 모든 인스턴스를 수정하려면 javaType 요소가 전역 Bindings 사용자 지정 요소의 자식으로 사용될 때 스키마 문서에서 XML Schema 유형의 모든 인스턴스를 수정합니다. 이러한 방식으로 사용되는 경우 수정되는 XML Schema 기본 유형을 식별하는 xmlType 특성 값을 지정해야 합니다.When it is used in this manner, you must specify a value for the xmlType attribute that identifies the XML Schema primitive type being modified.

    예 38.7. “글로벌 Primitive Type 사용자 정의” 스키마의 모든 인스턴스에 java.lang.Integer 를 사용하도록 코드 생성기에 지시하는 인라인 글로벌 사용자 지정을 보여줍니다.

    예 38.7. 글로벌 Primitive Type 사용자 정의

    <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 단순 형식의 모든 인스턴스에 대해 생성된 클래스를 수정합니다. 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 을 JAXB 속성 사용자 지정의 일부로 포함하여 복잡한 형식 정의의 개별 부분에 적용할 수 있습니다. javaType 요소는 속성의 baseType 요소에 자식으로 배치됩니다. javaType 요소를 사용하여 복잡한 유형 정의의 특정 부분을 수정하는 경우 xmlType 특성을 사용하지 마십시오.

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

    예 38.9. Complex 유형에서 요소 사용자 지정을 위한 파일 바인딩

    <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절. “Element 또는 Attribute의 기본 유형 지정” 을 참조하십시오.

38.2.3. 변환기 지정

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

예 38.10. JAXB Adapter 클래스

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 메서드를 식별해야 합니다. 다음 두 가지 방법 중 하나로 메서드의 이름을 지정할 수 있습니다.

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

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

중요

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

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

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

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

38.2.4. 생성된 내용

“변환기 지정” 에서 언급한 바와 같이 javaType 사용자 지정 요소를 사용하면 XML Schema 기본 유형의 사용자 지정마다 하나의 어댑터 클래스를 생성합니다. 어댑터의 이름은 패턴 어댑터N 을 사용하여 순서대로 지정됩니다. 두 가지 기본 유형 사용자 지정을 지정하는 경우 코드 생성기는 Adapter1Adapter2 의 두 가지 어댑터 클래스를 생성합니다.

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

XML Schema construct가 전역적으로 정의된 요소인 경우 형식에 대해 생성된 개체 팩토리 메서드는 다음과 같이 기본 메서드에서 수정됩니다.When the XML Schema construct is a globally defined element, the object factory method generated for the type is modified from the default method as follows:

  • 이 메서드는 @XmlJavaTypeAdapter 주석으로 장식됩니다.

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

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

예 38.11. “Global Element에 대한 사용자 정의 Object Factory Method” 예 38.7. “글로벌 Primitive Type 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 보여줍니다.

예 38.11. Global Element에 대한 사용자 정의 Object Factory Method

 @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 속성은 다음과 같이 수정됩니다.

  • 속성은 @XmlJavaTypeAdapter 주석으로 장식됩니다.

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

  • 속성의 @XmlElement 에는 형식 속성이 포함되어 있습니다.

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

  • 속성은 @XmlSchemaType 주석으로 장식됩니다.

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

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

예 38.12. “사용자 정의 복잡성 유형” 예 38.7. “글로벌 Primitive Type 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 보여줍니다.

예 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 런타임에서는 javaType 요소에서 지정한 Java 클래스로 XML 기본 형식을 변환하는 방법을 알지 못합니다. 단, parseMethod 속성 및 printMethod 속성에 의해 지정된 메서드를 호출해야 합니다. 런타임에서 호출하는 메서드의 구현을 제공해야 합니다. 구현된 메서드는 XML 기본 형식의 어휘 구조로 작업할 수 있어야 합니다.The implemented methods must be able to working with the lexical structures of the XML primitive type.

데이터 변환 방법의 구현을 단순화하기 위해 Apache CXF는 javax.xml.bind.DatatypeConverter 클래스를 제공합니다. 이 클래스는 모든 XML 스키마 기본 유형을 구문 분석하고 인쇄하는 메서드를 제공합니다. 구문 분석 메서드는 XML 데이터를 문자열 표현하고 표 34.1. “XML Schema Primitive Type to Java Native Type Mapping” 에 정의된 기본 유형의 인스턴스를 반환합니다. 인쇄 메서드는 기본 형식의 인스턴스를 사용 하 고 XML 데이터의 문자열 표현을 반환 합니다.The print methods take an instance of the default type and they return a string representation of the XML data.

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 런타임은 값이 제공되지 않는 경우 기본 변환기를 대체합니다.

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