DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 利用 Amazon Web Services 集成企業應用程序 2(2)
利用 Amazon Web Services 集成企業應用程序 2(2)
編輯:XML詳解     

制造商實現

  該解決方案的最後一個組件是制造商的 Order Processing Service,它是基於 Java 的服務,負責處理來自分銷商的訂單。Order Processing Service:

  輪詢購買訂單隊列,該隊列包含由分銷商發送的購買訂單。

  在收到購買訂單之後,它創建一個訂單匯總,並使用另一個 Amazon SQS 隊列將其發送回給分銷商。

  刪除分銷商發送來的購買訂單。

  制造商應用程序包含 表 5 中的業務實體。

  表 5. 制造商應用程序中的業務實體

類 描述 AddresssEntity 包含一個客戶或業務地址 CustomerOrderEntity 包含客戶訂單(購買訂單) CustomerOrderDetailEntity 包含每個客戶訂單(購買訂單)的商品細節 MessageQueueEntity 包含消息隊列項(即購買訂單或訂單匯總) OrderSummaryEntity 包含訂單發貨匯總 OrderSummaryDetailEntity 包含訂單發貨匯總的商品細節

  這個解決方案對所有數據庫操作使用 JdbcQuery 幫助類。此外,還使用另外兩個幫助類:DateUtil 用於格式化數據;AppConfig 用於讀取配置參數。SqsDataProvider 類同時也是提供 Amazon SQS 功能的實用程序類。

  制造商訂單處理服務

  OrderProcessingService 類負責根據在 AppConfig.propertIEs 文件中指定的輪詢時間間隔處理購買訂單。該服務獲取尚未發貨的購買訂單列表,並處理這些訂單。清單 20 中的 getMessageQueueItems 方法展示了如何使用 Java 代碼從特定的 Amazon SQS 隊列獲取消息列表。

  清單 20. getMessageQueueItems() 方法

   
protected ArrayList<HashMap<String, String>> getMessageQueueItems(String queueName) { 
ArrayList<HashMap<String, String>> results = new ArrayList<HashMap<String, String>>(); 
 
try { 
 String accessKeyId = AppConfig.getProperty("AmazonAccessKeyID"); 
 String secretAccessKey = AppConfig.getProperty("AmazonSecretAccessKey"); 
 
 AmazonSQS service = new AmazonSQSClIEnt(accessKeyId, secretAccessKey); 
  
 // get messages from queue 
 ReceiveMessageRequest request = new ReceiveMessageRequest(); 
 request.setQueueName(queueName); 
 request.setVisibilityTimeout(1); 
  
 ReceiveMessageResponse response = service.receiveMessage(request); 
  
 // if received response 
 if (response.isSetReceiveMessageResult()) { 
      System.out.println("\tReceive Message Result"); 
      ReceiveMessageResult receiveMessageResult = 
          response.getReceiveMessageResult(); 
      
      // get all messages and iterate through them 
      List<Message> messageList = receiveMessageResult.getMessage(); 
      for (Message message : messageList) { 
          // build hashmap containing each message 
          HashMap<String, String> row = new HashMap<String, String>(); 
          
          if (message.isSetMessageId()) { 
              row.put(COLUMN_ID, message.getMessageId()); 
              System.out.println("\t\tMessageId: " + 
                   message.getMessageId()); 
          } 
          if (message.isSetReceiptHandle()) { 
              row.put(COLUMN_HANDLE, message.getReceiptHandle()); 
          } 
          if (message.isSetBody()) {                  
              row.put(COLUMN_MESSAGE, message.getBody()); 
          } 
          
          // add row 
          results.add(row); 
      } 
 }     
} catch (AmazonSQSException ex) { 
 System.out.println("Caught Exception: " + ex.getMessage()); 
 System.out.println("Response Status Code: " + ex.getStatusCode()); 
 System.out.println("Error Code: " + ex.getErrorCode()); 
 System.out.println("Error Type: " + ex.getErrorType()); 
 System.out.println("Request ID: " + ex.getRequestId()); 
 System.out.println("XML: " + ex.getXML()); 
} 
 
return results; 
} 

  PurchaSEOrderSerializer 類負責將消息中的 XML 內容反序列化到 Java 類。您將使用 JDOM 來解析 XML 內容,如 清單 21 所示。(對於理解這段代碼,參考 清單 7 中的購買訂單模式會有幫助)。

  清單 21. PurchaSEOrderSerializer 類

   
public class PurchaSEOrderSerializer { 
 
public CustomerOrderEntity deserializePO(MessageQueueEntity message) { 
 CustomerOrderEntity order = null; 
  
 String XML = message.getMessageBody(); 
 System.out.println("Purchase Order:\n" + XML); 
  
 try { 
      // Create input source from string containing XML 
      InputSource XMLIS = new InputSource(); 
      xmlIS.setCharacterStream(new StringReader(XML)); 
      
      // Initialize SAX Builder object 
      SAXBuilder builder = new SAXBuilder(); 
 
      // Build JDOM Document object from input source 
      Document doc = builder.build(XMLIS); 
      Element rootElem = doc.getRootElement(); 
      
      // get order id 
      String id = rootElem .getChildText("Id");     
      
      // create customer order 
      order = new CustomerOrderEntity(id); 
      
      // set order date 
      String dateStr = rootElem.getChildText("OrderDate"); 
      order.setOrderDate(DateUtil.getDate(dateStr)); 
       
      // get company (customer) address element node and parse it 
      Element addrElem = rootElem.getChild("Company"); 
      this.setCompanyAddress(order, addrElem); 
 
      // get vendor address element node and parse it 
      addrElem = rootElem.getChild("Vendor"); 
      this.setVendorAddress(order, addrElem); 
 
      // get order items list and parse it 
      Element itemsElem = rootElem.getChild("Items"); 
      this.setOrderItems(order, itemsElem); 
      
      System.out.println(order.toString()); 
 } catch (IOException e) { 
      e.printStackTrace(); 
 } catch (NullPointerException e) { 
      e.printStackTrace(); 
 } catch (JDOMException e) { 
      e.printStackTrace(); 
 } 
 return order; 
} 
 
private void setVendorAddress(CustomerOrderEntity order, Element addrElem) { 
 // get data from XML 
 String coName = addrElem.getChildText("CompanyName"); 
 String streetAddress = addrElem.getChildText("StreetAddress"); 
 String city = addrElem.getChildText("City"); 
 String state = addrElem.getChildText("State"); 
 String zipCode = addrElem.getChildText("ZipCode"); 
  
 AddressEntity coAddress = order.getVendorAddress(); 
  
 // build address entity object using data read from XML 
 AddressEntity coAddress = order.getCompanyAddress(); 
 coAddress.setCity(city); 
 coAddress.setCompanyName(coName); 
 coAddress.setStreetAddress(streetAddress); 
 coAddress.setState(state); 
 coAddress.setZipCode(zipCode); 
} 
  
private void setCompanyAddress(CustomerOrderEntity order, Element addrElem) { 
 // get data from XML 
 String coName = addrElem.getChildText("CompanyName"); 
 String streetAddress = addrElem.getChildText("StreetAddress"); 
 String city = addrElem.getChildText("City"); 
 String state = addrElem.getChildText("State"); 
 String zipCode = addrElem.getChildText("ZipCode"); 
  
 // build address entity object using data read from XML 
 AddressEntity coAddress = order.getCompanyAddress(); 
 coAddress.setCity(city); 
 coAddress.setCompanyName(coName); 
 coAddress.setStreetAddress(streetAddress); 
 coAddress.setState(state); 
 coAddress.setZipCode(zipCode); 
} 
 
private void setOrderItems(CustomerOrderEntity order, Element itemsElem) { 
 List itemList = itemsElem.getChildren(); 
 if (itemList == null) return; 
  
 // iterate through all items in collection 
 for (int index = 0; index < itemList.size(); index++) { 
      // get current element 
      Element curElem = (Element) itemList.get(index); 
      
      // get item values 
      String itemId = curElem.getAttributeValue("Id"); 
      String itemName = curElem.getAttributeValue("Name"); 
      String quantity = curElem.getAttributeValue("Quantity"); 
      
      // create order item 
      CustomerOrderDetailEntity detail = new CustomerOrderDetailEntity(); 
      detail.setItemId(itemId); 
      detail.setItemName(itemName); 
      detail.setQuantity(Integer.parseInt(quantity)); 
  
      // add order item to order summary 
      order.addItem(detail); 
 } 
} 
} 

  接下來,為購買訂單構建訂單匯總。清單 22 顯示了所需的代碼。

  清單 22. getOrderSummaryForCustomerOrder() 方法

   
public OrderSummaryEntity getOrderSummaryForCustomerOrder( 
 CustomerOrderEntity customerOrder) { 
 
 if (customerOrder == null) return null; 
 
 // create order 
 OrderSummaryEntity orderSummary = new OrderSummaryEntity(); 
 orderSummary.setOrderDate(new Date()); 
 orderSummary.setReferenceId(customerOrder.getId()); 
 
 // set addresses 
 orderSummary.setCompanyAddress(customerOrder.getVendorAddress()); 
 orderSummary.setCustomerAddress(customerOrder.getCompanyAddress()); 
 
 // add items 
 Iterator<CustomerOrderDetailEntity> itemIter = customerOrder.getItems(); 
 while(itemIter.hasNext()) { 
 CustomerOrderDetailEntity item = itemIter.next(); 
  
 OrderSummaryDetailEntity detail = new OrderSummaryDetailEntity(); 
 detail.setItemId(item.getItemId()); 
 detail.setItemName(item.getItemName()); 
 detail.setQuantity(item.getQuantity()); 
  
 orderSummary.addItem(detail); 
 } 
 
 return orderSummary; 
}  

  然後,您必須將 OrderSummaryEntity 系列化到 XML。您需要使用 JDOM 系列化該消息,如 清單 23 所示。(參考 清單 8 中的訂單匯總模式會有幫助)。

  清單 23. OrderSummarySerializer 類

   
public class OrderSummarySerializer { 
 public String serializeOrder(OrderSummaryEntity order) { 
 Document doc = new Document(); 
  
 Element rootElem = new Element("OrderSummary"); 
 doc.addContent(rootElem); 
  
 // add id 
 Element idElem = new Element("OrderId"); 
 idElem.setText(order.getOrderId()); 
 rootElem.addContent(idElem); 
  
 // add reference id 
 Element referenceIdElem = new Element("ReferenceId"); 
 referenceIdElem.setText(order.getReferenceId()); 
 rootElem.addContent(referenceIdElem); 
  
 // add order date 
 Element dateElem = new Element("OrderDate"); 
 String dateStr = DateUtil.getDateString(new Date()); 
 dateElem.setText(dateStr);  
 rootElem.addContent(dateElem); 
  
 // set company address 
 Element addrElem = this.getElementForAddress("CompanyAddress", 
  order.getCompanyAddress()); 
 rootElem.addContent(addrElem); 
  
 // set customer address 
 addrElem = this.getElementForAddress("CustomerAddress", 
  order.getCustomerAddress()); 
 rootElem.addContent(addrElem); 
  
 // iterate through all items and add each item to order 
 Element itemsElem = new Element("Items"); 
 Iterator<OrderSummaryDetailEntity> itemIter = order.getItems(); 
 while(itemIter.hasNext()) { 
  OrderSummaryDetailEntity item = itemIter.next(); 
  
  Element itemElem = new Element("Item"); 
  itemElem.setAttribute("ItemId", item.getItemId()); 
  itemElem.setAttribute("ItemName", item.getItemName()); 
  String quantityStr = String.valueOf(item.getQuantity()); 
  itemElem.setAttribute("Quantity", quantityStr); 
  
  itemsElem.addContent(itemElem); 
 } 
 rootElem.addContent(itemsElem); 
  
 // convert XML document to string 
 XMLOutputter outp = new XMLOutputter(); 
 StringWriter strWriter = new StringWriter();     
 try { 
  outp.output(doc, strWriter); 
 } catch (IOException e) { 
  e.printStackTrace(); 
 }  
 return strWriter.toString(); 
 } 
 
 private Element getElementForAddress(String elemName, AddressEntity address) { 
 Element addrElem = new Element(elemName); 
  
 String coName = address.getCompanyName(); 
 String streetAddress = address.getStreetAddress(); 
 String cityName = address.getCity(); 
 String stateName= address.getState(); 
 String zipCode = address.getZipCode(); 
  
 Element coElem = new Element("CompanyName"); 
 coElem.setText(coName); 
 addrElem.addContent(coElem); 
  
 Element streetElem = new Element("StreetAddress"); 
 streetElem.setText(streetAddress); 
 addrElem.addContent(streetElem); 
  
 Element cityElem = new Element("City"); 
 cityElem.setText(cityName); 
 addrElem.addContent(cityElem); 
  
 Element stateElem = new Element("State"); 
 stateElem.setText(stateName); 
 addrElem.addContent(stateElem); 
  
 Element zipCodeElem = new Element("ZipCode"); 
 zipCodeElem.setText(zipCode); 
 addrElem.addContent(zipCodeElem); 
  
 return addrElem; 
 } 
}  

  使用 Amazon Java API 將 XML 消息發送到 Amazon SQS 隊列。清單 24 顯示了如何發送消息。

  清單 24. sendMessage() 方法

   
protected boolean sendMessage(String queueName, String messageBody) { 
boolean result = false; 
try { 
 String accessKeyId = AppConfig.getProperty("AmazonAccessKeyID"); 
 String secretAccessKey = AppConfig.getProperty("AmazonSecretAccessKey"); 
 
 AmazonSQS service = new AmazonSQSClIEnt(accessKeyId, secretAccessKey); 
 
 SendMessageRequest request = new SendMessageRequest(); 
 request.setQueueName(queueName); 
 request.setMessageBody(messageBody); 
 
 SendMessageResponse response = service.sendMessage(request); 
 // Send Message Response 
 if (response.isSetSendMessageResult()) { 
 System.out.println("\tSend Message Result"); 
 SendMessageResult sendMessageResult = response.getSendMessageResult(); 
 if (sendMessageResult.isSetMessageId()) { 
  System.out.println("\t\tMessageId: " + 
  sendMessageResult.getMessageId()); 
  result = true; 
 } 
 }  
} catch (AmazonSQSException ex) { 
 System.out.println("Caught Exception: " + ex.getMessage()); 
 System.out.println("Response Status Code: " + ex.getStatusCode()); 
 System.out.println("Error Code: " + ex.getErrorCode()); 
 System.out.println("Error Type: " + ex.getErrorType()); 
 System.out.println("Request ID: " + ex.getRequestId()); 
 System.out.println("XML: " + ex.getXML()); 
} 
 
return result; 
} 

  最後,您必須從 Amazon SQS 隊列刪除購買訂單隊列項。清單 25 顯示了如何刪除消息。

  清單 25. deleteMessage() 方法

   
protected boolean deleteMessage(String queueName, String handle) { 
boolean result = false; 
 
try { 
 String accessKeyId = AppConfig.getProperty("AmazonAccessKeyID"); 
 String secretAccessKey = AppConfig.getProperty("AmazonSecretAccessKey"); 
 
 AmazonSQS service = new AmazonSQSClIEnt(accessKeyId, secretAccessKey); 
 DeleteMessageRequest request = new DeleteMessageRequest(); 
 request.setQueueName(queueName); 
 request.setReceiptHandle(handle); 
 
 DeleteMessageResponse response = service.deleteMessage(request); 
 
 // Delete Message Response 
 if (response.isSetResponseMetadata()) { 
 // Response Metadata 
 ResponseMetadata responseMetadata = response.getResponseMetadata(); 
 if (responseMetadata.isSetRequestId()) { 
  System.out.print("RequestId: " + 
  responseMetadata.getRequestId()); 
  result = true; 
 } 
 } 
} catch (AmazonSQSException ex) { 
 System.out.println("Caught Exception: " + ex.getMessage()); 
 System.out.println("Response Status Code: " + ex.getStatusCode()); 
 System.out.println("Error Code: " + ex.getErrorCode()); 
 System.out.println("Error Type: " + ex.getErrorType()); 
 System.out.println("Request ID: " + ex.getRequestId()); 
 System.out.println("XML: " + ex.getXML()); 
} 
 
return result; 
} 

  測試解決方案

  現在,您可以測試這個解決方案了。為此,為庫存不足的商品提交一個訂單。然後,您可以跟蹤整個過程:

  提交訂單

  分銷商推遲訂單並創建一個購買訂單

  制造商接收訂單並向分銷商發送訂單匯總

  分銷商收到訂單匯總並處理推遲的訂單

  圖 6 中的分銷商客戶端在添加新訂單之前顯示庫存余量。

  圖 6. 浏覽庫存

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。

  圖 7 顯示了訂單提交窗口。

  圖 7. 提交訂單

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。

  圖 8 顯示了 Browse Orders 窗口。

  圖 8. 浏覽訂單

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。

  在添加了新的訂單之後,圖 9 中的窗口顯示了當該訂單被推遲時的訂單完成服務的輸出。

  圖 9. 分銷商訂單完成和庫存管理服務

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。

  在添加了新的訂單之後,圖 10 中的窗口顯示了 POQueue 消息隊列的內容。

  圖 10. 查看消息隊列

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。

  制造商接收來自消息隊列的購買訂單並處理它。圖 11 顯示了制造商的訂單處理系統的輸出。

  圖 11. 制造商的訂單管理服務

利用 Amazon Web Services 集成企業應用程序 2

  圖片看不清楚?請點擊這裡查看原圖(大圖)。 

  結束語

  本文演示了如何利用 XML 和 Amazon SQS Web 服務集成企業業務應用程序。通過將 XML 的擴展性和 Amazon SQS 結合起來可以提供靈活的、伸縮性強的應用程序。這個解決方案的主要益處是伸縮性、擴展性和集成的便捷性。該集成不需要考慮任何防火牆或安全問題。這個解決方案的最後一個好處是 —— 同時也是 Web 服務的關鍵驅動力 —— 它是跨平台的,並且不受所采用技術的技術的影響。制造商和分銷商在集成業務流程以促進運營效率和提高投資收益時,仍然可以保留現有的技術平台。

  這個解決方案也存在一些局限性。首先,Amazon SQS 的消息體的最大尺寸為 8KB。您可以通過其他可行的辦法繞過這一限制:

  使用 Amazon Simple Storage Service (Amazon S3) 存儲大型 XML 文檔,並為 Amazon SQS 消息中的 Amazon S3 項添加一個句柄。

  使用 Amazon SimpleDB 存儲結構化數據,並為 Amazon SQS 消息中的項添加句柄。

  第二個限制是 Amazon 應用於隊列的最終一致性方法。這有好的一面也有壞的一面,但 Amazon 肯定認為其好處是多於壞處的。該解決方案的最後一個限制就是沒有優先級或 FIFO 方法。再次強調一下,Amazon 是有意這樣設計的,因為它能提供伸縮性更強、可用性更高以及更可靠的解決方案。

  如果您在消息體中使用 XML 進行數據交換,最佳實踐建議您執行 XML Schema (XSD) 驗證,以確保發送器和接收器使用相同的語言。就像在其他 XML 集成項目中一樣,發送器和接收器需要使用通用的模式。

  下載

描述 名字 大小 下載方法 分銷商應用程序 C# 項目 NETSolution.zip 223KB HTTP 制造商應用程序 Java 項目 JavaSolution.zip 24KB HTTP 配置腳本 DbScripts.zip 1KB HTTP


XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved