37.3. 위젯 벤더 예

37.3.1. 위젯 명령 인터페이스

이 섹션에서는 Apache CXF에서 실제 애플리케이션을 해결하기 위해 사용되는 대체 그룹의 예를 보여줍니다. 서비스 및 소비자는 예 37.2. “Complex Types을 사용하는 대체 그룹” 에 정의된 위젯 대체 그룹을 사용하여 개발됩니다. 이 서비스는 checkWidgetsplaceWidgetOrder 라는 두 가지 작업을 제공합니다. 예 37.12. “위젯 명령 인터페이스” 주문 서비스의 인터페이스를 표시합니다.

예 37.12. 위젯 명령 인터페이스

<message name="widgetOrder">
  <part name="widgetOrderForm" type="xsd1:widgetOrderInfo"/>
</message>
<message name="widgetOrderBill">
  <part name="widgetOrderConformation"
        type="xsd1:widgetOrderBillInfo"/>
</message>
<message name="widgetMessage">
  <part name="widgetPart" element="xsd1:widget" />
</message>
<message name="numWidgets">
  <part name="numInventory" type="xsd:int" />
</message>
<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
  </operation>
  <operation name="checkWidgets">
    <input message="tns:widgetMessage" name="request" />
    <output message="tns:numWidgets" name="response" />
  </operation>
</portType>

예 37.13. “위젯 주문 SEI” 에는 인터페이스에 대해 생성된 Java SEI가 표시됩니다.

예 37.13. 위젯 주문 SEI

@WebService(targetNamespace = "http://widgetVendor.com/widgetOrderForm", name = "orderWidgets")
@XmlSeeAlso({com.widgetvendor.types.widgettypes.ObjectFactory.class})
public interface OrderWidgets {

    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "numInventory", targetNamespace = "", partName = "numInventory")
    @WebMethod
    public int checkWidgets(
        @WebParam(partName = "widgetPart", name = "widget", targetNamespace = "http://widgetVendor.com/types/widgetTypes")
        com.widgetvendor.types.widgettypes.WidgetType widgetPart
    );

    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "widgetOrderConformation", targetNamespace = "", partName = "widgetOrderConformation")
    @WebMethod
    public com.widgetvendor.types.widgettypes.WidgetOrderBillInfo placeWidgetOrder(
        @WebParam(partName = "widgetOrderForm", name = "widgetOrderForm", targetNamespace = "")
        com.widgetvendor.types.widgettypes.WidgetOrderInfo widgetOrderForm
    ) throws BadSize;
}
참고

예제에서는 대체 그룹의 사용만 보여 주므로 일부 비즈니스 논리는 표시되지 않습니다.

37.3.2. CheckWidgets 작업

37.3.2.1. 개요

CheckWidgets 는 대체 그룹의 헤드 멤버인 매개 변수가 있는 간단한 작업입니다. 이 작업에서는 대체 그룹의 멤버인 개별 매개 변수를 처리하는 방법을 보여줍니다. 소비자는 매개변수가 대체 그룹의 유효한 멤버인지 확인해야 합니다. 서비스에서는 요청에 전송된 대체 그룹의 멤버를 올바르게 결정해야 합니다.

37.3.2.2. 소비자 구현

생성된 메서드 서명은 대체 그룹의 head 요소 유형을 지원하는 Java 클래스를 사용합니다. 대체 그룹의 멤버 요소는 head 요소 또는 head 요소의 유형에서 파생 된 형식의 동일한 유형 중 하나이므로 대체 그룹의 멤버를 지원하기 위해 생성된 Java 클래스는 head 요소를 지원하기 위해 생성된 Java 클래스에서 상속됩니다. Java의 유형 계층 구조는 기본적으로 상위 클래스 대신 하위 클래스를 사용할 수 있도록 지원합니다.

Apache CXF가 대체 그룹 및 Java 유형 계층 구조에 대한 유형을 생성하는 방법 때문에 클라이언트는 특수 코드를 사용하지 않고 checkWidgets() 를 호출할 수 있습니다. checkWidgets() 를 호출할 논리를 개발할 때 위젯 대체 그룹을 지원하기 위해 생성된 클래스 중 하나의 개체로 전달할 수 있습니다.

예 37.14. “consumer Invoking checkWidgets() checkWidgets() 를 호출하는 소비자를 표시합니다.

예 37.14. consumer Invoking checkWidgets()

System.out.println("What type of widgets do you want to order?");
System.out.println("1 - Normal");
System.out.println("2 - Wood");
System.out.println("3 - Plastic");
System.out.println("Selection [1-3]");
String selection = reader.readLine();
String trimmed = selection.trim();
char widgetType = trimmed.charAt(0);
switch (widgetType)
{
  case '1':
  {
    WidgetType widget = new WidgetType();
    ...
    break;
  }
  case '2':
  {
    WoodWidgetType widget = new WoodWidgetType();
    ...
    break;
  }
  case '3':
  {
    PlasticWidgetType widget = new PlasticWidgetType();
    ...
    break;
  }
  default :
    System.out.println("Invaid Widget Selection!!");
}

proxy.checkWidgets(widgets);

37.3.2.3. 서비스 구현

checkWidgets() 서비스의 구현은 위젯 Type 오브젝트로 위젯 설명을 가져오고, 위젯의 인벤토리를 확인하고, 주식의 위젯 수를 반환합니다. 대체 그룹을 구현하는 데 사용되는 모든 클래스는 동일한 기본 클래스에서 상속되므로 JAXB 특정 API를 사용하지 않고 checkWidgets() 를 구현할 수 있습니다.

위젯에 대한 대체 그룹의 멤버를 지원하기 위해 생성된 모든 클래스는 위젯 Type 클래스 확장합니다. 이 사실 때문에 instanceof 를 사용하여 전달된 위젯 유형을 확인하고, 필요한 경우 widgetPart 오브젝트를 보다 제한적인 유형으로 캐스팅할 수 있습니다. 적절한 유형의 오브젝트가 있으면 위젯의 올바른 종류를 확인할 수 있습니다.

예 37.15. “CheckWidgets()의 서비스 구현() 가능한 구현을 보여줍니다.

예 37.15. CheckWidgets()의 서비스 구현()

public int checkWidgets(WidgetType widgetPart)
{
  if (widgetPart instanceof WidgetType)
  {
    return checkWidgetInventory(widgetType);
  }
  else if (widgetPart instanceof WoodWidgetType)
  {
    WoodWidgetType widget = (WoodWidgetType)widgetPart;
    return checkWoodWidgetInventory(widget);
  }
  else if (widgetPart instanceof PlasticWidgetType)
  {
    PlasticWidgetType widget = (PlasticWidgetType)widgetPart;
    return checkPlasticWidgetInventory(widget);
  }
}

37.3.3. placeWidgetOrder 작업

37.3.3.1. 개요

placeWidgetOrder 는 대체 그룹을 포함하는 두 가지 복잡한 유형을 사용합니다. 이 작업은 Java 구현에서 이러한 구조를 사용하는 방법을 보여줍니다. 소비자와 서비스 둘 다 대체 그룹의 멤버를 가져오고 설정해야 합니다.

37.3.3.2. 소비자 구현

placeWidgetOrder() 를 호출하려면 소비자가 위젯 대체 그룹의 하나의 요소가 포함된 위젯 순서를 구성해야 합니다. 주문에 위젯을 추가할 때 소비자는 대체 그룹의 각 요소에 대해 생성된 개체 팩토리 메서드를 사용해야 합니다. 이렇게 하면 런타임 및 서비스가 순서를 올바르게 처리할 수 있습니다. 예를 들어, 플라스틱 위젯에 대한 순서가 배치되는 경우 ObjectFactory.createPlasticWidget() 메서드는 순서에 추가하기 전에 요소를 만드는 데 사용됩니다.

예 37.16. “하위 그룹 멤버 설정” 위젯 OrderInfo 개체의 위젯 속성 을 설정하기 위 한 소비자 코드를 표시합니다.

예 37.16. 하위 그룹 멤버 설정

ObjectFactory of = new ObjectFactory();

WidgetOrderInfo order = new of.createWidgetOrderInfo();
...
System.out.println();
System.out.println("What color widgets do you want to order?");
String color = reader.readLine();
System.out.println();
System.out.println("What shape widgets do you want to order?");
String shape = reader.readLine();
System.out.println();
System.out.println("What type of widgets do you want to order?");
System.out.println("1 - Normal");
System.out.println("2 - Wood");
System.out.println("3 - Plastic");
System.out.println("Selection [1-3]");
String selection = reader.readLine();
String trimmed = selection.trim();
char widgetType = trimmed.charAt(0);
switch (widgetType)
{
  case '1':
  {
    WidgetType widget = of.createWidgetType();
    widget.setColor(color);
    widget.setShape(shape);
    JAXB<WidgetType> widgetElement = of.createWidget(widget); order.setWidget(widgetElement);
    break;
  }
  case '2':
  {
    WoodWidgetType woodWidget = of.createWoodWidgetType();
    woodWidget.setColor(color);
    woodWidget.setShape(shape);
    System.out.println();
    System.out.println("What type of wood are your widgets?");
    String wood = reader.readLine();
    woodWidget.setWoodType(wood);
    JAXB<WoodWidgetType> widgetElement = of.createWoodWidget(woodWidget); order.setWoodWidget(widgetElement);
    break;
  }
  case '3':
  {
    PlasticWidgetType plasticWidget = of.createPlasticWidgetType();
    plasticWidget.setColor(color);
    plasticWidget.setShape(shape);
    System.out.println();
    System.out.println("What type of mold to use for your
                        widgets?");
    String mold = reader.readLine();
    plasticWidget.setMoldProcess(mold);
    JAXB<WidgetType> widgetElement = of.createPlasticWidget(plasticWidget); order.setPlasticWidget(widgetElement);
    break;
  }
  default :
    System.out.println("Invaid Widget Selection!!");
    }

37.3.3.3. 서비스 구현

placeWidgetOrder() 메서드는 WidgetOrderInfo 개체 형태로 주문을 수신하고, 주문을 처리하며, 위젯 OrderBillInfo 개체 형태로 소비자에게 청구서를 반환합니다. 주문은 일반 위젯, 플라스틱 위젯 또는 목재 위젯일 수 있습니다. 주문한 위젯 유형은 widget OrderForm 오브젝트의 위젯 속성에 저장되는 오브젝트 유형에 따라 결정됩니다. 위젯 속성은 대체 그룹이며 위젯 요소, woodWid get 요소 또는 plasticWidget 요소를 포함할 수 있습니다.

구현은 순서에 따라 가능한 요소 중 어느 것이 저장되는지 결정해야합니다. 이 작업은 JAXBElement<? 확장 T > 개체의 getName() 메서드를 사용하여 요소의 QName을 결정합니다. 그런 다음 QName을 사용하여 대체 그룹의 요소를 순서대로 결정할 수 있습니다. 청구서에 포함된 요소가 알려지면 해당 값을 적절한 유형의 개체로 추출할 수 있습니다.

예 37.17. “placeWidgetOrder()구현” 가능한 구현을 보여줍니다.

예 37.17. placeWidgetOrder()구현

public com.widgetvendor.types.widgettypes.WidgetOrderBillInfo placeWidgetOrder(WidgetOrderInfo widgetOrderForm)
{
  ObjectFactory of = new ObjectFactory();

  WidgetOrderBillInfo bill = new WidgetOrderBillInfo()

   // Copy the shipping address and the number of widgets
   // ordered from widgetOrderForm to bill
   ...

  int numOrdered = widgetOrderForm.getAmount();

  String elementName = widgetOrderForm.getWidget().getName().getLocalPart();
  if (elementName.equals("woodWidget")
  {
    WoodWidgetType widget=order.getWidget().getValue();
    buildWoodWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<WoodWidgetType> widgetElement = of.createWoodWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.75;
    bill.setAmountDue(amtDue);
  }
  else if (elementName.equals("plasticWidget")
  {
    PlasticWidgetType widget=order.getWidget().getValue();
    buildPlasticWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<PlasticWidgetType> widgetElement = of.createPlasticWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.90;
    bill.setAmountDue(amtDue);
  }
  else
  {
    WidgetType widget=order.getWidget().getValue();
    buildWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<WidgetType> widgetElement = of.createWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.30;
    bill.setAmountDue(amtDue);
  }

  return(bill);
}

예 37.17. “placeWidgetOrder()구현” 의 코드는 다음을 수행합니다.

요소를 만들기 위해 개체 팩토리를 인스턴스화합니다.Sertss an object factory to create elements.

위젯 OrderBillInfo 개체를 인스턴스화하여 청구서를 보유합니다.

정렬된 위젯 수를 가져옵니다.Gets the number of widgets ordered.

순서에 저장된 요소의 로컬 이름을 가져옵니다.Gets the local name of the element stored in the order.

요소가 woodWidget 요소인지 확인합니다.

요소의 값을 순서에서 적절한 유형의 개체로 추출합니다.

bill에 있는 JAXBElement<T > 개체를 만듭니다.

bill 개체의 위젯 속성 설정합니다.

bill 개체의 amountDue 속성을 설정합니다.