37.3. 小部件供应商示例
37.3.1. 小部件顺序接口
本节演示了 Apache CXF 中用于解决实际应用程序的替换组示例。使用 例 37.2 “使用复杂类型替换组” 中定义的小部件替换组来开发服务和使用者。该服务提供两种操作: checkWidgets
和 placeWidgetOrder
。例 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 “小部件 Ordering SEI” 显示为接口生成的 Java SEI。
例 37.13. 小部件 Ordering 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 Operation
概述
checkWidget
是一个简单操作,它有一个参数是替换组的头成员。此操作演示了如何处理作为替换组成员的单个参数。消费者必须确保 参数是替换组的成员。该服务必须正确决定在请求中发送的替换组的成员。
消费者实施
生成的方法签名使用 Java 类,支持替换组的 head 元素类型。由于替换组的 member 元素与 head 元素或来自 head 元素的类型相同,所以生成的 Java 类是支持从 Java 类继承的替换组的成员来支持 head 元素。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);
服务实施
服务实施的 checkWidgets ()
获取一个小部件描述作为 WidgetType
对象,检查小部件清单,并返回库存中的小部件数量。由于用于实施替换组的所有类都继承自同一基础类,因此您无需使用任何 JAXB 特定的 API,即可实施 checkWidgets ()
。
所有生成的类都用于支持 widget
扩展 WidgetType
类的替换组的成员。鉴于这一事实,您可以使用 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 Operation
概述
placeWidgetOrder
使用两个包含替换组的复杂类型。此操作演示了在 Java 实施中使用这种结构。使用者和服务都必须获取和设置替换组的成员。
消费者实施
若要调用 placeWidgetOrder ()
,消费者必须构建包含小部件替换组的某一元素的小部件顺序。将小部件添加到订单时,使用者应使用为替换组的每个元素生成的对象工厂方法。这样可确保运行时和服务可以正确处理顺序。例如,如果将某一顺序放在 plastic 小部件,则使用 ObjectFactory.createPlasticWidget ()
方法创建元素,然后再将其添加到订购前。
例 37.16 “设置 Substitution 组成员” 显示用于设置 WidgetOrderInfo
对象 的小部件
属性使用者代码。
例 37.16. 设置 Substitution 组成员
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!!"); }
服务实施
placeWidgetOrder ()
方法以 WidgetOrderInfo
对象的形式收到顺序,处理订购过程,并以 WidgetOrderBill
的形式将 bill 返回给消费者。订单可以是纯文本小部件,也可以是一个wooden 小部件。排序的小部件类型由
对象的小部件属性中存储什么类型来决定。widget
OrderFormwidget
属性是一个替换组,可以包含 小部件
元素、woodWidget
元素或 plasticWidget
元素。
该实施必须确定哪些可能元素按照顺序存储。这可以使用 JAXBElement< 扩展了 T&
gt; 对象的 getName ()
方法来确定元素的 QName。然后,可以使用 QName 来决定替换组中的哪个元素按顺序排列。当 bill 中包含的元素被已知后,您可以将其值提取到正确的对象类型。
例 37.17 “Implementation of placeWidgetOrder()
” 显示可能的实施。
例 37.17. Implementation of 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 “Implementation of placeWidgetOrder()
” 中的代码执行以下操作:
实例化对象工厂以创建元素。
实例化 小部件OrderBillInfo
对象来容纳 bill。
获取排序的小部件数量。
获取以顺序存储的元素的本地名称。
检查该元素是否是 woodWidget
元素。
将元素的值从 的顺序提取到正确的对象类型。
创建一个指向 bill 的 JAXBElement<T
> 对象。
设置 bill 对象的 widget
属性。
设置对象的数量 属性
。