text:
Trước khi bạn bắt đầu
Hướng dẫn này giải thích giao diện khám phá và mô tả thống nhất hoặc UDDI (Uniform Description and Discovery Interface). UDDI xác định một đăng ký của các dịch vụ Web và thông tin công ty khác và được thiết kế để cung cấp một cách khám phá các dịch vụ Web mới để sử dụng và trong các trường hợp lý tưởng, tự động hoá việc sử dụng chúng.
Hướng dẫn này giả định rằng bạn đã quen thuộc với các khái niệm chung của các dịch vụ Web, cũng như SOAP. Kiến thức về WSDL cũng có ích, nhưng hướng dẫn này chỉ xem xét lại các khái niệm nói chung.
Để làm theo cùng các mã trong phần cuối, bạn nên hiểu rõ về Java, nhưng các khái niệm, như phần còn lại của hướng dẫn, áp dụng cho bất kỳ ngôn ngữ lập trình nào.
Về loạt bài này
Loạt bài hướng dẫn này dạy các khái niệm cơ bản về các dịch vụ Web bằng cách tiếp tục khai thác về tờ báo hư cấu, Daily Moon (Mặt trăng hàng ngày), như là các nhân viên sử dụng các dịch vụ Web để tạo ra một hệ thống tiến trình công việc để tăng năng suất khi có nhiều thay đổi.
Phần 1 đã giải thích các khái niệm cơ bản sau các dịch vụ Web và đã hiển thị cách sử dụng SOAP, đặc tả này làm cơ sở cho hầu hết những gì sắp tới, kết nối phòng chuyên mục rao vặt với Hệ thống quản lý nội dung.
Phần 2, đưa mọi thứ tiến một bước xa hơn, khi giải thích cách sử dụng WSDL (Web Services Description Language - Ngôn ngữ mô tả các dịch vụ Web) để định nghĩa các thông báo được tạo với những thứ mà người ta hy vọng ở dịch vụ Web, cho phép nhóm làm việc tạo các dịch vụ và các ứng dụng khách kết nối với các thông báo dễ dàng hơn.
Phần 3 tìm nhóm làm việc có một số dịch vụ tại chỗ và có một mong muốn định vị các dịch vụ dễ dàng. Đáp lại, UDDI (Universal Description, Discovery and Integration - Tích hợp, khám phá và mô tả đa năng) cung cấp một đăng ký có thể tìm kiếm được của các dịch vụ có sẵn bằng cách đưa ra công khai các dịch vụ riêng của chúng cho những người khác.
Phần 4 và 5, Các dịch vụ Web-An ninh (WS-Security) và Các dịch vụ Web-Chính sách (WS-Policy), tìm nhóm làm việc có mục tiêu là bảo vệ của các dịch vụ của tờ báo và những thay đổi mà các nhóm làm việc cần phải thực hiện để truy cập các dịch vụ mới được bảo vệ đó.
Tính tương thích là từ khóa trong phần 6, do các dịch vụ từ những sự hiện thực khác nhau phải được truy cập từ một hệ thống duy nhất. Phần 6 trình bày các yêu cầu và các thử nghiệm liên quan đến việc cấp chứng chỉ Các dịch vụ Web-Tính tương thích (WS-I).
Cuối cùng, phần 7 cho thấy cách sử dụng WS-BPEL (Ngôn ngữ thực hiện qui trình kinh doanh) để tạo các ứng dụng phức tạp từ các dịch vụ riêng biệt.
Bây giờ hãy xem xét hướng dẫn này trình bày những gì cụ thể hơn một chút.
Về hướng dẫn này
Phần 1 của loạt bài này giới thiệu cho bạn các dịch vụ Web và nhấn mạnh tầm quan trọng của SOAP. Chúng tôi đã làm điều này thông qua việc khai thác của một phòng chuyên mục rao vặt của tờ báo hư cấu Daily Moon. Trong Phần 2 của loạt bài này, phòng chuyên mục rao vặt quyết định tạo ra một dịch vụ Web của riêng mình, tạo tài liệu sử dụng của mình bằng WSDL (Ngôn ngữ mô tả các dịch vụ Web). Ở đây trong Phần 3, về các dịch vụ Web chủ báo đã quyết định đưa tất cả ra khỏi các dịch vụ và đã yêu cầu sử dụng một đăng ký UDDI để theo dõi tất cả các dịch vụ có sẵn.
Trong tiến trình hướng dẫn này, bạn sẽ học:
- UDDI là gì.
- UDDI dành cho cái gì.
- Cấu trúc của dữ liệu UDDI.
- Làm thế nào để biểu diễn có hiệu quả WSDL khi sử dụng UDDI.
- Các hoạt động mà bạn có thể thực hiện trên dữ liệu UDDI.
- Tương tác với một đăng ký UDDI bằng cách sử dụng Java.
Điều kiện cần trước
Để làm theo cùng với các mã cho hướng dẫn này, bạn sẽ cần có sẵn phần mềm sau đây:
Thực hiện Apache Geronimo hay thực hiện một UDDI khác. Để làm theo cùng với các mã, bạn sẽ cần truy cập vào một đăng ký UDDI. Đến cuối hướng dẫn, kiểu đăng ký nào mà bạn sử dụng không quan trọng, do UDDI về cơ bản là một dịch vụ Web và cần được truy cập từ nền tảng hay ngôn ngữ bất kỳ, tới nền tảng hoặc ngôn ngữ bất kỳ khác. Điều đó nói rằng, các máy chủ ứng dụng Apache Geronimo cũng là cơ sở cho IBM Community Edition (Ấn bản cộng đồng của WebSphere của IBM) và chúng tôi đã sử dụng máy chủ đó trong Phần 1 và 2 của loạt bài này, có thực hiện đăng ký UDDI của Apache, jUDDI, được cài đặt sẵn và cấu hình như là một phần của một cài đặt tiêu chuẩn. Bạn có thể tải Apache Geronimo từ Apache.org. Để biết thêm thông tin về cài đặt Geronimo, xem Phần 1 của loạt bài này.
UDDI4J -- Để truy cập đăng ký, hướng dẫn này giải thích việc sử dụng dự án UDDI4J, cung cấp một sự tích hợp khá chặt chẽ giữa các khái niệm UDDI và mã Java. Bạn có thể tải UDDI4J từ Sourceforge.net.
Apache Axis2 hoặc việc thực hiện SOAP khác -- Bạn có thể tạo các thông báo SOAP bằng tay và bạn có thể giải thích chúng bằng tay, nhưng thật thoải mái để có một sự thực hiện có ích. Bạn sẽ sử dụng Apache Axis2, bao gồm các việc thực hiện của các API có liên quan đến-SOAP khác nhau để làm cho cuộc sống của bạn dễ dàng hơn đáng kể. Bạn có thể tải Apache Axis2 từ Apache.org. Hướng dẫn này sử dụng phiên bản 0.94, nhưng phiên bản mới hơn cũng sẽ hoạt động.
Ấn bản tiêu chuẩn Java 2 phiên bản 1.4 -- Tất cả mọi thứ trong các công cụ này dựa trên Java, như là các dịch vụ và các ứng dụng khách mà bạn sẽ xây dựng trong hướng dẫn này. Bạn có thể tải J2SE SDK từ Sun Developer Network. Geronimo sẽ không chạy đúng với Java 1.5.
Bạn cũng sẽ cần một trình duyệt Web và một trình soạn thảo văn bản, nhưng tôi chắc chắn rằng bạn đã có chúng rồi. Nếu bạn muốn, bạn cũng có thể sử dụng một IDE như Eclipse, nhưng do chúng ta đang tập trung vào các công nghệ hơn là các công cụ, nên chúng ta sẽ chỉ sử dụng một trình soạn thảo văn bản và dòng lệnh để chỉnh sửa các tệp của chúng ta và biên dịch chúng.
Tổng quan
Chúng ta hãy nhìn vào nơi chúng ta ở đó cho đến nay.
Câu chuyện cho đến nay
Loạt bài này cho phép các nhân viên của tờ báo hư cấu Daily Moon khi tờ báo này chuyển nhiều hoạt động hàng ngày của mình sang một hệ thống dựa trên các dịch vụ Web. Trong Phần 1, Phòng chuyên mục rao vặt tìm hiểu về SOAP bằng cách tương tác với Hệ thống quản lý nội dung và trong Phần 2, họ đã tạo dịch vụ riêng của mình và đã định nghĩa nó bằng cách sử dụng WSDL. Bây giờ Rudy, chủ báo, bị ấn tượng với cách mà các dịch vụ Web đang làm việc trong tổ chức của mình đến mức ông muốn nhìn thấy các dịch vụ Web được sử dụng thường xuyên hơn, thậm chí đến mức tương tác với các tổ chức khác.
Cuối cùng, ông đã yêu cầu hai thành viên của nhóm Công nghệ thông tin, Gene và Francis, tạo một đăng ký dịch vụ Web, mà ông hy vọng sẽ cho phép các phòng khác dễ dàng tìm thấy những gì họ cần để chuyển các hoạt động của họ qua các dịch vụ Web.
Hai nhân viên này quyết định cách tốt nhất để làm điều đó sẽ là triển khai thực hiện một đăng ký của giao diện UDDI. Đăng ký này sẽ cho phép họ không chỉ lưu thông tin trên các dịch vụ riêng của tờ báo, mà nó cũng có thể tương tác với các đăng ký tại các tờ báo khác.
Trình làm mới WSDL
Một phần của quá trình đăng ký một dịch vụ với một đăng ký UDDI bao gồm việc thao tác định nghĩa WSDL, vì vậy trước khi chuyển sang dự án mới, Gene xem xét lại các khái niệm cơ bản của WSDL bằng cách quay lại qua các tệp được tạo ra trong dự án sau cùng của mình. Xem Liệt kê 1.
Liệt kê 1. Các tệp WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.daily-moon.com/classifieds" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace="http://www.daily-moon.com/classifieds"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://org.apache.axis2/xsd" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:element name="createNewAdRequest"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="content" /> <xs:element type="xs:string" name="endDate" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="createNewAdResponse"> <xs:complexType> <xs:sequence> <xs:element type="xs:int" name="newAdId" /> </xs:sequence> </xs:complexType> </xs:element> ... </xs:schema> </wsdl:types> <wsdl:message name="createNewAdRequestMessage"> <wsdl:part name="part1" element="ns1:createNewAdRequest" /> </wsdl:message> <wsdl:message name="createNewAdResponseMessage"> <wsdl:part name="part1" element="ns1:createNewAdResponse" /> </wsdl:message> <wsdl:message name="getExistingAdsResponseMessage"> ... </wsdl:message> <wsdl:portType name="ClassifiedServicePortType"> <wsdl:operation name="createNewAd"> <wsdl:input message="tns:createNewAdRequestMessage" /> <wsdl:output message="tns:createNewAdResponseMessage" /> </wsdl:operation> <wsdl:operation name="finalizeIssue">...</wsdl:operation> <wsdl:operation name="editExistingAd">...</wsdl:operation> <wsdl:operation name="getExistingAds">...</wsdl:operation> </wsdl:portType> <wsdl:binding name="ClassifiedServiceBinding" type="tns:ClassifiedServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <wsdl:operation name="createNewAd"> <soap:operation soapAction="createNewAd" style="document" /> <wsdl:input> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="finalizeIssue">...</wsdl:operation> <wsdl:operation name="editExistingAd">...</wsdl:operation> <wsdl:operation name="getExistingAds">...</wsdl:operation> </wsdl:binding> <wsdl:service name="ClassifiedService"> <wsdl:port name="ClassifiedServicePort" binding="tns:ClassifiedServiceBinding"> <soap:address location= "http://www.daily-moon.com:8080/axis2/services/ClassifiedService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Chúng tôi đã gỡ bỏ một số đoạn trong tài liệu này vì các lý do không gian của bài viết này, nhưng chúng ta hãy xem lại các khái niệm chung.
Bắt đầu từ phía dưới cùng, chúng ta có dịch vụ thực tế, có sẵn tại một vị trí cụ thể
và triển khai thực hiện giao diện
ClassifiedServiceBinding. Người ta đã biểu thị giao diện đó như là một ràng
buộc, chỉ rõ các hoạt động được quy định trong portType
ClassifiedServicePortType.
portType định nghĩa
các thông báo nhập vào và xuất ra bằng cách sử dụng các phần tử được quy định trong
phần các kiểu.
Một ứng dụng khách XML có thể đọc thông tin này và sử dụng nó để truy cập vào dịch vụ Web. (Hoặc chính xác hơn, một công cụ tạo ứng dụng khách của dịch vụ Web có thể đọc thông tin này và tạo một ứng dụng khách có thể truy cập vào dịch vụ Web).
Từ đây chúng ta đi đâu
Trong tiến trình hướng dẫn này, Gene và Francis sẽ tách thông tin của tờ báo Daily Moon thành các cấu trúc thân thiện-UDDI, bao gồm thông tin nghiệp vụ và thông tin dịch vụ. Họ sẽ sử dụng nó để nhập các thông tin và các dịch vụ của tờ báo vào một đăng ký UDDI bằng cách sử dụng UDDI4J. Họ cũng sẽ làm việc với đăng ký riêng của một tờ báo khác, tờ Daily Star, để tìm kiếm một dịch vụ cung cấp điểm số của các môn thể thao đang diễn ra.
Bây giờ hãy xem tất cả mọi thứ về UDDI.
Giới thiệu về UDDI
UDDI về cơ bản là một dịch vụ Web, nhưng UDDI rất khác so với SOAP và WSDL nên để hiểu được một nền tảng nhỏ trước khi chúng ta bắt đầu là rất tốt.
Tại sao là UDDI?
Khi tất cả các ứng dụng là cục bộ, thật khá dễ dàng để tìm những gì bạn muốn. Tuy nhiên, khi bạn có một hệ thống phân tán như các dịch vụ Web, bạn không có lợi ích gì về việc có một kho lưu trữ trung tâm nữa. Hệ thống phân tán cũng dễ bị thay đổi. Đây là thế giới trong đó UDDI hình thành. UDDI được dự định để phục vụ hai mục đích. Theo sự tạo hình ban đầu của mình, UDDI đã được diễn đạt như là một loại "Đăng ký doanh nghiệp đa năng" (Universal Business Registry). Ý tưởng là điều mà các doanh nghiệp có thể tìm kiếm các đối tác bằng cách sử dụng một trong ba phương pháp sau:
- "Các trang trắng": Các trang trắng giống như các trang trắng của danh bạ điện thoại, trong đó người ta có thể tìm kiếm thông tin về một công ty. Ví dụ, nếu bạn đã biết tên của công ty, bạn có thể tìm ra công ty đó ở đâu, cách để liên hệ với họ và thậm chí cả liên hệ với ai trong tổ chức đó.
- "Các trang vàng": Các trang vàng, cũng vậy, giống như các trang trắng của danh bạ điện thoại, trong đó bạn có thể tra cứu các doanh nghiệp dựa trên sự phân loại. UDDI đã quy định các sự phân loại khác nhau mà các công ty có thể sử dụng để phân loại chính mình. Ví dụ, nếu bạn đang tìm kiếm các đồ thể thao, bạn có thể tìm các công ty có một mã số của hệ thống phân loại công nghiệp Bắc Mỹ (NAICS) là 339.920.
- "Các trang xanh": Đúng, không có các trang xanh lá cây trong danh bạ điện thoại của bạn, nhưng ý tưởng là ở chỗ các công ty có thể sử dụng phương pháp tìm kiếm này để tìm các đối tác thương mại đã triển khai thực hiện một dịch vụ cụ thể. Ví dụ, bạn có thể thực hiện tìm kiếm các công ty triển khai thực hiện một tính toán từ xa bằng cách sử dụng các mã bưu điện (zip).
Người ta cũng nghĩ UDDI như là một cách để giữ cho các ứng dụng phân tán hoạt động trong thời gian dài. Ý tưởng là bạn sẽ nhớ nhanh thông tin về cách truy cập một dịch vụ cụ thể và nếu khách hàng của bạn bị ngắt, ứng dụng sẽ tự động quay trở về chỗ đăng ký và kiểm tra để xem các thông tin đã thay đổi chưa. Nếu nó đã thay đổi, bạn có thể chỉ cần tạo các thay đổi trong ứng dụng của bạn (một cách tự động, trong một thế giới lý tưởng) và thử lại yêu cầu của bạn.
UDDI trong thế giới thực
Khi đang tìm kiếm một UBR (Đăng ký doanh nghiệp đa năng), Francis đã phát hiện ra rằng UBR đã không còn tồn tại nữa. Trong thực tế, các nhà tài trợ cho công ty của nó đã ngừng UBR khi UDDI phiên bản 3.0 được phát hành. Tại sao? Đúng, bất kể ý tưởng UBR đã là tốt như thế nào, thực tế là hầu như không ai sử dụng nó. Lý do gồm hai phần: đầu tiên, đã có rất ít thông tin có ích trong UBR -- trừ khi, đó là, bạn đang tìm kiếm một dịch vụ về số lượng cổ phiếu được bán ra tại thị trường chứng khoán, trong trường hợp này bạn có thể tìm thấy khá phong phú. Lý do thứ hai là các công ty, theo quy luật, không thực hiện kinh doanh với các tổ chức mà họ không hiểu rõ. Rất ít các tổ chức, nếu có, sẽ thực hiện một sự tìm kiếm tự động đối với các đối tác thương mại và sau đó mở hệ thống của họ cho các đối tác đó mà không có một chút chú trọng thích hợp nào. Vì vậy mô hình tìm kiếm tự động và gọi ra đã không thực sự cất cánh.
Mô hình đó cũng bị cản trở bởi thực tế là UDDI đã đi trước thời của nó, theo một số cách. Được thiết kế để xử lý tất cả các kiểu dịch vụ và không chỉ SOAP trên HTTP, UDDI không thêm ngay chính mình vào việc sử dụng các định nghĩa WSDL, ít nhất là trong khung nhìn của những thứ đang cố gắng sử dụng UDDI.
Tuy nhiên, điều đó không nói rằng UDDI không còn được sử dụng chút nào nữa. Thay vào đó, trên thực tế nó đang được sử dụng như một "đăng ký riêng" nhiều hơn. Các công ty tạo các đăng ký riêng của mình và nhập vào các dịch vụ riêng của mình. UDDI cũng có thể được sử dụng và là một kiểu đăng ký kinh doanh bên trong, theo cách mà từ đó người ta sử dụng LDAP theo truyền thống.
Hơn nữa, khi chúng ta chuyển qua một cách suy nghĩ "chỉ có dịch vụ Web" nhiều hơn về một ý tưởng SOA (Kiến trúc hướng dịch vụ), khả năng để xử lý nhiều hơn chỉ có mình SOAP có thể chỉ chứng tỏ bản thân nó khi chạy lâu dài.
Cấu trúc dữ liệu UDDI
Thông tin được chứa trong một đăng ký UDDI bao gồm năm kiểu khác nhau:
businessEntityhoặc tổ chức công ty thực tế. Điều này có thể có nghĩa là toàn bộ tổ chức hoặc nó có thể là một tổ chức liên kết hoặc chi nhánh.
publisherAssertionhoặc mối quan hệ giữa
businessEntities. Để hợp lệ
publisherAssertionsphải được cả hai bên yêu cầu (vì vậy tôi không thể yêu cầu là một chi nhánh của một công ty khác), trừ khi cả hai thực thể có trách nhiệm với chủ báo hoặc trừ khi cả hai thực thể được nhập vào trong đăng ký bằng một tài khoản người dùng giống nhau.
bindingTemplate, về cơ bản là đặc tả của một giao diện của một dịch vụ. Nhiều businessServices có thể thực hiện
businessServices.
businessServicehay một dịch vụ do một doanh nghiệp cung cấp. Bây giờ, điều đó có vẻ đơn giản, nhưng trong thế giới của UDDI, điều đó không nhất thiết có nghĩa là nó là một dịch vụ Web. Ví dụ, bạn thực sự có thể xác định dịch vụ hỗ trợ điện thoại của doanh nghiệp của bạn (có nghĩa là số điện thoại thực tế mà người dùng quay số và tất cả mọi thứ mà đi kèm với nó) như một dịch vụ UDDI. Tất nhiên, bạn sẽ không có một tài liệu WSDL giả, nhưng nó sẽ là một dịch vụ được doanh nghiệp của bạn cung cấp.
tModelshoặc các mô hình siêu dữ liệu. Khi nghiên cứu UDDI, Francis đi đến kết luận rằng tModel có lẽ là lý do lớn nhất tại sao UDDI đã không cất cánh như mong đợi. Như một đăng ký của các dịch vụ, bạn sẽ mong đợi tìm thấy một cách để trực tiếp xác định giao diện cho một dịch vụ, như WSDL thực hiện. Nhưng, như đã nói, UDDI đã chưa bao giờ được dự định là độc quyền về các dịch vụ Web và được thiết kế với linh hoạt hơn nữa.
tModelsthực hiện trợ giúp trỏ đến các tài liệu XML, như chúng ta sẽ thấy sau này, nhưng trong thực tế chúng có nghĩa là một cách tổng quát để xác định thông tin về thứ gì đó, thông qua dịch vụ, một doanh nghiệp hay bất cứ điều gì khác.
Đó là những cấu trúc dữ liệu cơ bản của UDDI. Bây giờ hãy xem và cách thức trong đó UDDI nói chúng ta có thể tương tác với chúng.
API của UDDI
UDDI nổi danh là quá phức tạp, nhưng với cốt lõi của mình UDDI thuộc về năm kiểu dữ liệu được mô tả ở trên, được kết hợp với bốn hoạt động: tìm kiếm, nhận, lưu và xóa. Nói cách khác, đặc tả UDDI lưu ý những điều sau đây để bạn có thể thực hiện với dữ liệu:
find_xx: Những phương thức này, chẳng hạn như
find_businessEntity,
find_businessServicevà v.v, cung cấp một cách để bạn tìm kiếm một bản ghi trong đăng ký UDDI. Những phương thức này trả về khóa để nhận dạng đối tượng.
get_xx: Một khi bạn có khóa duy nhất nhận dạng một đối tượng, bạn có thể sử dụng
get_xx methods, như
get_businessServicevà v.v, để lấy ra chính đối tượng thực tế đó. Ví dụ,
get_businessServicetrả về toàn bộ đối tượng
businessService, từ đó bạn thu được bất kỳ thông tin nào mà bạn cần.
save_xx: Như bạn có thể đã đoán được, các phương thức này thêm thông tin vào cơ sở dữ liệu hoặc chúng thay đổi thông tin đã có trong cơ sở dữ liệu.
delete_xx: Những phương thức này, chẳng hạn như
delete_bindingTemplate,
delete_tModel, và v.v, lấy khóa duy nhất của đối tượng làm tham số và loại bỏ nó khỏi cơ sở dữ liệu. Hành vi thực tế của các phương thức này phụ thuộc vào những gì bạn đang xóa. Ví dụ, vì
tModelsthường xuyên được các đối tượng khác trong cơ sở dữ liệu tham chiếu, nên chúng có thể không thực sự bị xóa; để thay thế người ta ẩn chúng đi
Hầu như tất cả mọi thứ của UDDI dựa trên 20 phân cắt giữa năm đối tượng (
businessService,
bindingTemplate,
publisherAssertion,
businessEntity và
tModel) và bốn hành động
(
find,
get,
save và
delete).
Bây giờ hãy xem cấu trúc này thực sự trông giống như thế nào.
Cấu trúc dữ liệu UDDI
Để bắt đầu quá trình thêm công ty vào một đăng ký UDDI, Francis đã định nghĩa thông tin để nhập vào đăng ký đó.
businessEntity
Bước đầu tiên là nhập chính tờ báo đó vào đăng ký. Để làm điều này, Francis tạo một
đối tượng
businessEntity. Đối tượng này chứa thông tin về
doanh nghiệp, vừa để xác định doanh nghiệp và vừa để cung cấp thông tin về doanh
nghiệp. Ví dụ, đối tượng businessEntity có nhiều hơn một tên, (cho phép bạn, ít nhất
là, tạo một phần tử tên cho mỗi ngôn ngữ trong đó công ty được thể hiện), thông tin
liên hệ (người ta bảo Francis thêm Pat Mooney làm liên hệ chính), các dịch vụ liên
kết với các thực thể (Gene sẽ làm sau) và thông tin để nhận dạng và phân loại công
ty.
Mặc dù hầu hết mọi người sẽ không bao giờ tương tác với Đăng ký của UDDI (UDDI Registry) theo cách này, thực tế là về cơ bản UDDI là một ứng dụng SOAP; tất cả các hoạt động mà bạn thực hiện xảy ra như là kết quả của các thông báo SOAP được chuyển qua lại. Điều này có nghĩa là businessEntity do Francis đang tạo ra cuối cùng được biểu diễn như một phần tử XML. Xem Liệt kê 2.
Liệt kê 2. Phần tử
businessEntity
<businessEntity businessKey="{uuid}" operator="(optional)" authorizedName="(optional)"> <discoveryURLs> <discoveryURL></discoveryURL> <discoveryURL></discoveryURL> </discoveryURLs> <name>The Daily Moon</name> <name lang="fr-ca">La Lune Quotidienne</name> <description></description> <contacts> <contact> <description></description> <personName>Pat Mooney</personName> <phone></phone> <email>patm@daily-moon.com</email> <address useType="optional, billing, etc." sortCode="optional" tModelKey="optional"> <addressLine></addressLine> <addressLine></addressLine> <addressLine></addressLine> </address> </contact> <contact> ... </contact> </contacts> <businessServices> <businessService serviceKey="required" businessKey="optional"> ... </businessService> </businessServices> <identifierBag> ... </identifierBag> <categoryBag> ... </categoryBag> </businessEntity>
Một bản ghi
businessEntity thực hiện phải không quá phức
tạp. Trong thực tế, chỉ có một tên duy nhất và trình nhận dạng duy nhất để hoạt động
như là
businessKey (Khóa doanh nghiệp) cần thiết. Tuy
nhiên, để cho đầy đủ, tôi đã bao gồm toàn bộ cấu trúc, trừ một số đoạn bị cắt mà
chúng tôi sẽ nói về chúng sau đây. Trong một môi trường sản xuất các phần tử rỗng cần
được gỡ bỏ.
Hãy xem xét một số thông tin ở đây.
Bắt đầu từ trên cùng, một lần nữa,
businessKey, là một
trình nhận dạng. Toán tử và các thuộc tính
authorizedName
được ứng dụng đăng ký xử lý nội bộ, bạn không cần phải chạm vào chúng, nhưng chúng
đại diện cho thực thể chạy ứng dụng đăng ký đó và người hoặc tài khoản mà người nào
đó đã thêm vào bản ghi.
discoveryURLs được thêm vào đăng ký mỗi khi một
businessEntity được lưu vào đăng ký. Các URL này có nghĩa là một vị trí mà người sử
dụng có thể đi tới đó để có thêm nhiều thông tin về
businessEntity này.
Lưu ý là Francis đã thêm một tên bổ sung khác, biểu thị tên của tờ báo bằng tiếng
Pháp, ở đây tờ báo này đang cố gắng quảng cáo rùm beng để lôi kéo doanh nghiệp. Mỗi
một trong số những thực thể này mang thuộc tính
lang xác
định mã cho ngôn ngữ đang nói đến. Bạn có thể cung cấp các tên thay thế từ các chữ
viết tắt phổ biến, ví dụ, IBM thay cho International Business Machines.
Mô tả tùy chọn sắp tới chỉ là một chuỗi văn bản. Trong thực tế, hầu hết các phần tử chính trong UDDI có một mô tả tùy chọn.
Tiếp theo, Francis có thể thêm nhiều mối liên hệ hơn nữa. Đối với mỗi liên hệ anh ta
có thể xác định nhiều hay ít thông tin khi cần thiết
personName thường được cung cấp, nhưng các thông tin như số điện thoại,
e-mail và v.v được cung cấp dựa trên ý muốn của những người có liên quan, do tất cả
các thông tin trong Đăng ký UDDI (Registry UDDI) là công khai cho tất cả người dùng.
Các liên hệ cũng có thể có một địa chỉ, với
useType quy
định cụ thể loại địa chỉ. Ví dụ, trong trường hợp của một mối liên hệ, thông tin có
thể là địa chỉ nhà so với thông tin công việc và v.v. Trong trường hợp của một công
ty,
useType có thể là văn phòng chính, trung tâm phân phối
và v.v.
Phần tử
businessServices liệt kê các dịch vụ bất kỳ đã
được liên kết với
businessEntity này. Vì Gene vẫn chưa
thêm bất kỳ các dịch vụ nào, nên phần tử này thường vẫn rỗng. Hai mục cuối cùng,
identifierBag và
categoryBag, cung cấp thêm thông tin về chính công ty đó và được sử dụng
trong tìm kiếm. Chúng ta sẽ xem xét từng thứ trong chúng ngay sau đây.
publisherAssertion
Một
publisherAssertion là một câu lệnh về mối quan hệ của
một
businessEntity này với một businessEntity khác. Ví dụ,
Francis biết rằng một trong những mục tiêu của dự án này là sử dụng một dịch vụ được
cung cấp trong tờ báo Daily Star, trong đó tờ Daily Star cung cấp các điểm số của các
môn thể thao cho tờ Daily Moon. Điều đó khiến cho tờ Daily Star trở
thành một nhà cung cấp nội dung cho tờ Daily Moon.Francis có thể biểu thị điều
đó như thể hiện trong Liệt kê 3.
Liệt kê 3.
publisherAssertion
<publisherAssertion> <fromKey>(businessKey for Daily Star)</fromKey> <toKey>(businessKey for Daily Moon)</toKey> <keyedReference tModelKey="904BD800-D53A-11DA-B055-850A1DA99D79" keyName="optional" keyValue="CONTENTPROVIDER" /> </publisherAssertion>
Các phần tử
fromKey và
toKey
biểu thị các mã nhận dạng (ID) duy nhất cho hai thực thể có liên quan. Trong trường
hợp này, đó là tờ Daily Moon và tờ Daily Star. Tờ Daily Star là
nhà cung cấp nội dung cho tờ Daily Moon, do đó, các khóa được đặt cho phù hợp.
Chúng ta sẽ thấy
keyedReference (Tham chiếu có khóa) nhiều
lần. Trong trường hợp này, chúng ta sẽ nói rằng chính tham chiếu đó là một nhà cung
cấp nội dung.
keyValue (Giá trị khóa) là thuộc tính duy
nhất cần thiết cho một
keyedReference, nhưng cũng bình
thường để bao gồm một
keyName (Tên khóa) cho dễ đọc và một
tModelKey để nhận dạng một kiểu tham chiếu cụ thể.
Trong trường hợp này
tModelKey biểu thị cho vùng tên của
các hiệp hội giữa các tờ báo đối lập với các đại diện bên trong. Một lát nữa chúng ta
sẽ nói thêm về
tModels.
businessService
Tiếp theo, Francis cần nhập thông tin về các dịch vụ thực tế bất kỳ mà tờ Daily Moon
sắp cung cấp. Một đối tượng
businessService chứa hai mẩu
thông tin chính ngoài
serviceKey duy nhất cần thiết và
tên. Chúng là
bindingTemplates và bất kỳ các thể loại nào
mà dịch vụ này thuộc về chúng. Xem Liệt kê 4.
Liệt kê 4.
businessService
<businessService serviceKey="required" businessKey="optional"> <name></name> <description></description> <bindingTemplates> <bindingTemplate serviceKey="optional" bindingKey="required"> ... </bindingTemplate> </bindingTemplates> <categoryBag> ... </categoryBag> </businessService>
BindingTemplate
Tmodelinstancedetails là một sự biểu thị về nó tương thích
với những ứng dụng hoặc các đặc tả nào. Xem Liệt kê 5.
Liệt kê 5. The
bindingTemplate
Một
bindingTemplate là thứ định nghĩa cả nơi người ta có
thể tìm thấy dịch vụ lẫn dịch vụ này làm gì, nghe có vẻ đơn giản. Tuy nhiên, cả hai
hàm này đảm nhận ý nghĩa mới trong nội dung của UDDI. Ví dụ, để xác định có thể truy
cập một dịch vụ ở đâu, bạn có thể cung cấp một
accessPoint, đại diện cho một URL đơn giản hoặc bất kỳ dữ liệu thích hợp
khác, chẳng hạn như một số điện thoại với một đường dây trợ giúp hoặc một
hostingRedirector.
Người ta thường sử dụng
hostingRedirector khi ràng buộc
cho một dịch vụ thay đổi. Ví dụ, nếu tờ Daily Moon đã thiết lập dịch vụ các
đoạn quảng cáo được phân loại của nó và cho phép cả hai tờ báo gửi các đoạn quảng cáo
lên bằng cách sử dụng cuộc gọi
createNewAdd(), thì tờ báo
này sẽ cần hoặc là đảm bảo rằng các dịch vụ không bao giờ thay đổi hoặc cung cấp một
cách để cho các ứng dụng khách biết dịch vụ đã thay đổi. Đó là nơi mà
hostingRedirector được dùng. Trong trường hợp đó, Francis
(hoặc trên thực tế là Gene) sẽ tạo ra một
bindingTemplate
mới, biểu thị cho các thông tin mới và nhập
bindingKey của
bindingTemplate đó vào trong thuộc tính
bindingKey của phần tử
hostingRedirector.
Việc xác định các dịch vụ làm gì thậm chí có thể còn khó khăn hơn. Lý do của việc này có hai phần. Trước tiên, vì chúng ta không nhất thiết phải nói về một dịch vụ SOAP, bạn không thể chỉ cần cung cấp một tệp WSDL. Thứ hai, vì điều này được hiểu là một quá trình tự động, nên bạn cần cung cấp thông tin này theo một cách như vậy là hoàn toàn rõ ràng.
Kết quả là
bindingTemplate bao gồm một phần tử
tModelInstanceDetails, trong đó có một hoặc nhiều phần tử
tModelInstanceDetail. Mỗi một trong số các phần tử đó
bao gồm một hoặc nhiều phần tử
tModelInstanceInfo, trỏ đến
một
tModel cụ thể. Một lần nữa, chúng ta sẽ nói về
tModels ngay sau đây. Tuy nhiên, điều quan trọng cần hiểu là
phần tử
tModelInstanceInfo có thể chứa một phần tử
instanceDetails, mà bản thân phần tử instanceDetails lại chứa
một
overviewDoc, bao gồm
overviewURL, một URL cho một tài liệu thực sự xác định dịch vụ đó. (Đúng,
đó là nơi bạn xác định tệp WSDL).
TModels (bao gồm cả
tModel của
tModels)
Bây giờ hãy nói về
tModels.
tModels thực sự nhằm vào hai mục đích. Đầu tiên, như chúng
ta đã thấy một chút trong cuộc thảo luận về
publisherAssertions, là một phần của "bộ chỉ thị vùng tên". Nói cách khác,
một
tModel có thể cung cấp cách để phân biệt giữa các kiểu
thông tin có thể dẫn đến nhầm lẫn. Một ví dụ như mã số thuế hoặc giá trị khác dễ nhầm
với các số. Ví dụ, một
keyedReference có những điều sau
dường như không cung cấp tất cả các thông tin, vì hai mã nhận dạng thuế này thuộc về
các nước khác nhau. Trong cả hai nước, chúng được gọi là mã số thuế, nhưng theo lập
trình, chúng ta phải có một cách để phân biệt giữa chúng, như trong Liệt kê 6.
Liệt kê 6. Các mã số thuế của các nước khác nhau
<keyedReference tModelKey="" keyName="taxid" keyValue="11111111" /> <keyedReference tModelKey="" keyName="taxid" keyValue="22222222" />
Đó là nơi một
tModel được dùng. Chúng ta có thể tạo một
mô hình chính cho "mã số thuế của Hoa Kỳ" và một mô hình cho "mã số thuế của Mexico"
và v.v. Một khi chúng ta tạo các mô hình đó, chúng ta có thể sử dụng các khóa
tModel của các mô hình để đánh giá kỹ hơn nữa các
keyedReferences. Xem Liệt kê 7.
Liệt kê 7.
tModels và
keyedReferences
<tModel tModelKey="902CDE50-D53A-11DA-B055-A74C17FA61A7"> <name>United States codes</name> </tModel> <tModel tModelKey="062377D0-D5F5-11DA-8170-8ACF057FECAD"> <name>Mexico codes</name> </tModel> <keyedReference tModelKey="902CDE50-D53A-11DA-B055-A74C17FA61A7" keyName="taxid" keyValue="11111111" /> <keyedReference tModelKey="062377D0-D5F5-11DA-8170-8ACF057FECAD" keyName="taxid" keyValue="22222222" />
Cách sử dụng khác của
tModel là như một trình nhận dạng
đặc tả. Ví dụ, Francis biết rằng Gene là sẽ tạo các mục cho
ClassifiedService mà hai nhân viên này đã làm trong tháng trước. Dịch vụ
này biểu thị một giao diện cụ thể và như vậy, người ta có thể nhận biết dịch vụ này
bằng cách sử dụng một
tModel.
tModel này có thể trông giống như thứ được hiển thị trong Liệt kê 8.
Liệt kê 8.
tModel
<tModel tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A" operator="optional" authorizedName="optional"> <name>Classified Service Interface</name> <description></description> <overviewDoc> <description></description> <overviewURL> http://www.daily-moon.com/ClassifiedService-interface.wsdl </overviewURL> <overviewDoc> <identifierBag> ... </identifierBag> <categoryBag> ... </categoryBag> </tModel>
Cũng như với mọi đối tượng khác mà chúng ta đã xem xét
tModel có một khóa duy nhất, đó là thông tin cần thiết duy nhất. Tuy
nhiên, trong trường hợp này, chúng ta cũng muốn xác định
overviewURL, có nghĩa là URL cho tệp WSDL của giao diện. (Chúng ta sẽ tạo
nó trong phần tiếp theo).
Một lần nữa, người ta có thể nhận biết
tModels bằng cách
sử dụng một
identifierBag và được phân loại bằng cách sử
dụng một
categoryBag. Hãy xem chúng hoạt động như thế
nào.
identifierBag
Vì UDDI nhằm vào tính linh hoạt, nên không có cách cụ thể nào để nhận biết một businessEntity. UDDI không yêu cầu nhận biết một doanh nghiệp theo số D-U-N-S của nó hoặc theo mã số thuế của nó hoặc bằng bất kỳ phương pháp nhận biết cụ thể khác. Thay vào đó, UDDI cung cấp một thùng chứa (container) trong đó bạn có thể đặt bao nhiều trình nhận dạng tùy ý khi cần thiết, như bạn thấy trong Liệt kê 9.
Liệt kê 9.
indentifierBag
Mỗi
keyedReference được bạn thêm vào trong một
identifierBag biểu thị cơ hội khác cho những người dùng tìm
thấy đối tượng đang nói đến trong một tìm kiếm.
categoryBag
categoryBag hoạt động như
identifierBag, trong đó nó có chứa một hoặc nhiều
keyedReferences. Xem Liệt kê 10.
Liệt kê 10.
categoryBag
<categoryBag> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag>
Trong trường hợp này, Francis đã tạo một
categoryBag cho
thấy rằng tờ Daily Moon là một văn phòng chi nhánh của tờ báo. Bây giờ hãy xem cách
sử dụng tất cả các đối tượng này.
Ánh xạ WSDL tới UDDI
Trước khi Gene có thể viết bất kỳ mã nào để gửi tất cả các thông tin này tới đăng ký UDDI, Gene phải thực hiện một kết nối quan trọng giữa các dịch vụ hiện tại của họ và UDDI. Gene phải làm thích nghi các dịch vụ hiện tại này với khái niệm của UDDI về các dịch vụ, các giao diện và các khuôn mẫu ràng buộc.
Các dịch vụ so với các giao diện
Cách nhìn của UDDI về một dịch vụ, như bạn có thể nhớ lại, bao gồm ba phần: giao
diện, được xác định bằng cách sử dụng
tModels;
businessService; và
bindingTemplate, liên kết hai trong số chúng lại với nhau. Vì vậy, bước
đầu tiên của Gene là tìm hiểu tệp WSDL định nghĩa dịch vụ SOAP có thể khớp trong cấu
trúc này như thế nào.
Bước đầu tiên của Gene là phân chia WSDL. May mắn thay, điều này khá đơn giản. Giao diện này bao gồm tất cả các mảnh của tệp WSDL trừ ra việc thực hiện thực tế của nó. Xem Liệt kê 11.
Liệt kê 11. Giao diện WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.apache.org/axis2" xmlns:axis2="http://ws.apache.org/axis2" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace="http://ws.apache.org/axis2"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://org.apache.axis2/xsd" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:element type="ns1:ClassifiedAd" name="ClassifiedAd" /> <xs:complexType name="ClassifiedAd"> <xs:sequence> <xs:element type="xs:int" name="id" /> <xs:element type="xs:string" name="content" /> <xs:element type="xs:string" name="endDate" /> <xs:element type="xs:string" name="startDate" /> </xs:sequence> </xs:complexType> ... </xs:schema> </wsdl:types> <wsdl:message name="createNewAdRequestMessage"> <wsdl:part name="part1" element="ns1:createNewAdRequest" /> </wsdl:message> <wsdl:message name="createNewAdResponseMessage"> <wsdl:part name="part1" element="ns1:createNewAdResponse" /> </wsdl:message> ... <wsdl:portType name="ClassifiedServicePortType"> <wsdl:operation name="finalizeIssue"> <wsdl:input message="tns:finalizeIssueRequestMessage" /> </wsdl:operation> <wsdl:operation name="createNewAd"> <wsdl:input message="tns:createNewAdRequestMessage" /> <wsdl:output message="tns:createNewAdResponseMessage" /> </wsdl:operation> ... </wsdl:portType> <wsdl:binding name="ClassifiedServiceBinding" type="tns:ClassifiedServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <wsdl:operation name="createNewAd"> <soap:operation soapAction="createNewAd" style="document" /> <wsdl:input> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:output> </wsdl:operation> ... </wsdl:binding> </wsdl:definitions>
Giao diện này bao gồm các định nghĩa kiểu (lược đồ XML), các thông báo bất kỳ
portType ngay cả
binding (ràng
buộc), bởi vì ràng buộc không đặc trưng cho việc thực hiện cụ thể.
Việc thực hiện bao gồm phần tử dịch vụ thực tế. Xem Liệt kê 12.
Liệt kê 12. Việc thực hiện dịch vụ WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns= "http://www.daily-moon.com/ClassifiedService-interface" xmlns:axis2="http://ws.apache.org/axis2" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace= "http://www.daily-moon.com/ClassifiedService-interface"> <wsdl:import namespace="http://ws.apache.org/axis2" location= "http://www.nicholaschase.com/ClassifiedService-interface.wsdl" /> <wsdl:service name="ClassifiedService"> <wsdl:port name="ClassifiedServicePort" binding="axis2:ClassifiedServiceBinding"> <soap:address location= "http://www.daily-moon.com:8080/axis2/services/ClassifiedService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Lưu ý rằng tệp thực hiện nhập khẩu tệp giao diện. Nói cách khác, tệp này là định nghĩa đầy đủ của dịch vụ.
Bây giờ hãy xem tệp đó tương ứng với các đối tượng UDDI của chúng ta như thế nào.
Ánh xạ giao diện tới một
tModel
Đầu tiên Gene đã phải ánh xạ giao diện tới một
tModel
thích hợp. Xem Liệt kê 13.
Liệt kê 13.
tModel
<tModel tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <name>http://www.daily-moon.com/ClassifiedService- interface</name> <description>Interface for the Daily Moon Classified Department web application</description> <overviewDoc> <description>WSDL interface document</description> <overviewURL> http://www.daily-moon.com/ClassifiedService-interface.wsdl </overviewURL> <overviewDoc> <categoryBag> <keyedReference tModelKey="C1ACF26D-9672-4404-9D70-39B756E62AB4" keyName="uddi-org:types" keyValue="wsdlSpec" /> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </tModel>
Bắt đầu từ phía dưới cùng, lưu ý
categoryBag. Gene đã thêm
vào hai
keyReferences. Tham chiếu đầu tiên quy định rằng
trên thực tế chúng ta đang xử lý một tệp WSDL. Người ta đã xác định trước
tModelKey cụ thể đó để biểu thị vùng tên
uddi-org:types. Tất cả các tệp WSDL phải được xác định theo cách này. Tham
chiếu thứ hai được liên kết với vùng tên
ntis-gov:naics:1997 do đó, thật dễ dàng cho những người dùng của Gene tìm
định nghĩa này trong số tất cả các tệp WSDL biểu thị các dịch vụ phải làm với các tờ
báo. Tiếp tục lên, chúng ta thấy
overviewDoc. Ngoài mô tả
tùy chọn, nó xác định URL thực tế mà chúng ta có thể tìm thấy tệp WSDL ở đó.
Cuối cùng, tên của
tModel phải khớp với vùng tên đích của
tệp WSDL.
Ánh xạ việc thực hiện với một khuôn mẫu ràng buộc
Tiếp theo Gene phải ánh xạ chính việc thực hiện này tới một
bindingTemplate. Xem Liệt kê 14.
Liệt kê 14.
bindingTemplate
<bindingTemplate serviceKey="" bindingKey=""> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> <tModelInstanceDetails> <tModelInstanceDetail> <tModelInstanceInfo tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <instanceDetails> <description>The canonical implementation of the Daily Moon's classified service.</description> <overviewDoc> <overviewURL> http://www.daily-moon.com/ClassifiedService-impl.wsdl </overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetail> </tModelInstanceDetails> </bindingTemplate>
Ở đây chúng ta thấy rằng Gene tạo một
bindingTemplate mới,
thiết lập
accessPoint như URL cho dịch vụ thực tế
modelInstanceDetails chủ yếu liên kết giao diện
tModel (qua
tModelKey) với tài
liệu thực hiện (được quy định trong
overviewDoc). Bây giờ
Gene chỉ phải tham chiếu nó từ dịch vụ.
Tham chiếu
bindingTemplate từ
businessService và
businessEntity
Bước cuối cùng là đặt
bindingTemplate tất cả lại với nhau
và tham chiếu
businessService và
businessService từ
businessEntity. Xem Liệt kê 15.
Liệt kê 15.
businessEntity đầy đủ
<businessEntity businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>The Daily Moon</name> <name lang="fr-ca">La Lune Quotidienne</name> <contacts> <contact> <personName>Pat Mooney</personName> <email>patm@daily-moon.com</email> </contact> </contacts> <businessServices> <businessService serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7"> <name>ClassifiedService</name> <bindingTemplates> <bindingTemplate bindingKey="904BD800-D53A-11DA-B055-850A1DA99D79"> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> <tModelInstanceDetails> <tModelInstanceDetail> <tModelInstanceInfo tModelKey= "66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <instanceDetails> <description>The canonical implementation of the Daily Moon's classified service.</description> <overviewDoc> <overviewURL> http://www.daily-moon.com/ClassifiedService-impl.wsdl </overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetail> </tModelInstanceDetails> </bindingTemplate> </bindingTemplates> <categoryBag> <keyedReference tModelKey="C1ACF26D-9672-4404-9D70-39B756E62AB4" keyName="uddi-org:types" keyValue="wsdlSpec" /> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </businessService> </businessServices> <identifierBag> <keyedReference tModelKey="4064C064-6D14-4F35-8953-9652106476A9" keyName="DUNS Number" keyValue="55555555" /> <keyedReference tModelKey="" keyName="US Tax ID" keyValue="111111111" /> </identifierBag> <categoryBag> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </businessEntity>
Nói cách khác, dịch vụ đã hoàn tất: bây giờ Gene có một
businessEntity bao gồm một dịch vụ
Tìm và sử dụng thông tin
Bây giờ tất cả các thông tin có trong dịch vụ, ít nhất về mặt lý thuyết, Gene cần phải xem xét quá trình để tìm kiếm thông tin một lần nữa.
Các việc tìm kiếm của UDDI hoạt động như thế nào: tìm kiếm một doanh nghiệp
Việc tìm kiếm trong UDDI gồm hai bước. Đầu tiên, bạn tìm khóa của đối tượng mà bạn
muốn và sau đó bạn lấy thông tin về đối tượng đó. Cuối cùng, để cho Gene tìm một
doanh nghiệp, Gene cần tạo một yêu cầu
find_business, như
trong Liệt kê 16.
Liệt kê 16. Tìm một doanh nghiệp theo thể loại
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <categoryBag> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </find_business>
Yêu cầu này sẽ tìm tất cả các doanh nghiệp khớp với các thể loại được tham chiếu
trong
categoryBag. Các việc tìm kiếm về giá trị
categoryBag được xử lý như một việc tìm kiếm ""VÀ" (AND). Nói
cách khác, mục bất kỳ trùng khớp ít nhất là một trong các thể loại phải khớp. Bạn
cũng có thể xác định một tìm kiếm
identifierBag theo cách
này. Tuy nhiên, Gene không thực sự quan tâm đến tìm kiếm theo thể loại. Vào lúc này,
Gene chỉ muốn xem có hay không có doanh nghiệp trong đăng ký, do đó để thay thế Gene
thích tìm kiếm theo tên hơn, như trong Liệt kê 17.
Liệt kê 17. Tìm một doanh nghiệp theo tên
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <name>daily</name> </find_business>
Lưu ý rằng một tìm kiếm theo tên được xử lý như thể tên mà bạn đang tìm kiếm tiếp sau
là một ký tự đại diện. Nói cách khác, việc tìm kiếm ở đây là giống như thực hiện một
tìm kiếm với
"daily*", do đó cả Daily Moon và
Daily Star và bất kỳ doanh nghiệp khác nào bắt đầu với từ "daily" sẽ hiển
thị. Những tìm kiếm này cũng phân biệt chữ hoa, chữ thường.
Việc tìm kiếm tìm thấy gì
find_business yêu cầu trả về một
businessList. Xem Liệt kê 18.
Liệt kê 18. Một tìm kiếm trả về các doanh nghiệp
<businessList generic="2.0" operator="uddi.sourceOperator" truncated="true" xmlns="urn:uddi-org:api_v2"> <businessInfos> <businessInfo businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691" > <name>The Daily Moon</name> <serviceInfos> <serviceInfo serviceKey= "064B4170-D5F5-11DA-8170-A74C17FA61A7"> <name>ClassifiedService</name> </serviceInfo> </serviceInfos> </businessInfo> <businessInfo> ... </businessInfo> </businessInfos> </businessList>
businessList bao gồm một phần tử
businessInfo cho mỗi
businessEntity thỏa mãn
tìm kiếm đó. Mỗi một trong số các phần tử
serviceInfo đó
có một
businessKey cho
businessEntity thực tế.
businessList cũng bao
gồm một phiên bản viết tắt của các thông tin sẽ được liệt kê trong
businessEntity, để bạn có thể có được một ý tưởng về liệu đây
có phải là một doanh nghiệp mà bạn đang tìm kiếm không.
Một khi bạn có
businessKey, thích hợp, bạn cần phải có
thêm thông tin về
businessEntity này.
Một khi bạn có khóa
Để có thêm thông tin về một
businessEntity cụ thể dựa trên
businessKey, bạn cần phải thực hiện một yêu cầu
get_businessDetail. Xem Liệt kê 19.
Liệt kê 19. Nhận thông tin về các doanh nghiệp
<get_businessDetail generic="2.0" xmlns="urn:uddi-org:api_v2" > <businessKey>1A3DB880-D5F4-11DA-B880-F94D3591C691 </businessKey> </get_businessDetail>
Bạn có thể liệt kê càng nhiều
businessKeys trong một yêu
cầu
get_businessDetail như bạn muốn. Mỗi một businessKeys
sẽ có phần tử
businessDetail riêng của mình trong các kết
quả. Xem Liệt kê 20.
Liệt kê 20. Các chi tiết về doanh nghiệp được trả về
<businessDetail generic="2.0" operator="uddi.sourceOperator" truncated="false" xmlns="urn:uddi-org:api_v2"> <businessEntity businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>The Daily Moon</name> <name lang="fr-ca">La Lune Quotidienne</name> <contacts> ... <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </businessEntity> </businessDetail>
Mỗi phần tử
businessDetail gồm toàn bộ
businessEntity của doanh nghiệp có liên quan.
Thay đổi cách tìm kiếm hoạt động
Trong lúc tìm kiếm này hoạt động, có những lúc bạn muốn thay đổi hành vi của tìm kiếm
đó. Ví dụ, có lẽ bạn muốn tìm kiếm một sự trùng khớp chính xác hơn là một sự trùng
khớp của ký tự đại diện hoặc bạn muốn tìm kiếm theo chữ hoa hay chữ thường. Bạn có
thể thay đổi hành vi của việc tìm kiếm bằng cách sử dụng
findQualifiers. Xem Liệt kê 21.
Liệt kê 21. Sử dụng
findQualifiers
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <findQualifiers> <findQualifier>sortByNameAsc</findQualifier> <findQualifiers> <name>daily</name> </find_business>
Trong trường hợp này, việc tìm kiếm sẽ tiến hành như bình thường, nhưng kết quả sẽ
được trả về được sắp xếp theo tên. Bạn có thể thêm nhiều phần tử
findQualifier như bạn muốn. Trong số các phần tử có sẵn để sử dụng là
exactNameMatch,
caseSensitiveMatch,
sortByNameDesc, sortByDateAsc và
sortByDateDesc,
hay
LikeKeys (báo cho đăng ký biết để xử lý các khóa trong
một
categoryBag hoặc
identifierBag như là một điều kiện "HOẶC" (OR) nếu chúng chia sẻ cùng một
tModelKey) và
combineCategoryBags (xử lý tất cả các
categoryBags của một
businessEntity, liệu chúng
có thuộc về
businessEntity,
businessService hoặc
bindingTemplate, không,
nếu như chúng thuộc về
businessService đó).
Tìm một kiểu dịch vụ
Gene cũng muốn đảm bảo rằng những người dùng có thể tìm bất kỳ dịch vụ nào dựa trên
một giao diện cụ thể. Ví dụ, truy vấn này sẽ định vị
bindingTemplates mà bạn sử dụng giao diện
ClassifiedService. Xem Liệt kê 22.
Liệt kê 22. Tìm một
bindingTemplate
<find_binding generic="2.0" xmlns="urn:uddi-org:api_v2" > <tModelBag> <tModelKey>66999A50-D5F4-11DA-9A50-FA44D6AD622A</tModelKey> </tModelBag> </find_binding>
Truy vấn này trả về một
serviceList. Xem Liệt kê 23.
Liệt kê 23. Các dịch vụ được trả về
<serviceList generic="2.0" operator="uddi.sourceOperator" xmlns="urn:uddi-org:api_v2"> <serviceInfos> <serviceInfo serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7" businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>ClassifiedService</name> </serviceInfo> </serviceInfos> </serviceList>
Như trong trường hợp với
find_business, sau đó bạn đã phải
quay trở lại đó và yêu cầu thông tin về
businessEntity,
rồi bạn sẽ xác định thông tin yêu cầu trên các máy chủ dựa trên
serviceKey. Xem Liệt kê 24.
Liệt kê 24. Nhận các chi tiết dịch vụ
<get_serviceDetail generic="2.0" xmlns="urn:uddi-org:api_v2" > <serviceKey>064B4170-D5F5-11DA-8170-A74C17FA61A7 </serviceKey> </get_serviceDetail>
Truy vấn này trả về một
serviceDetail cho mỗi
serviceKey cụ thể. Xem Liệt kê 25.
Liệt kê 25. Các chi tiết dịch vụ được trả về
<serviceDetail generic="2.0" operator="uddi.sourceOperator" xmlns="urn:uddi-org:api_v2"> <businessService serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7" businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>ClassifiedService</name> <bindingTemplates> <bindingTemplate bindingKey="904BD800-D53A-11DA-B055-850A1DA99D79"> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> ... <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </businessService> <businessService> ... </businessService> </serviceDetail>
Bây giờ Gene biết những gì mình muốn làm, anh ta sẵn sàng bắt đầu viết mã.
Làm việc với UDDI theo chương trình
Công việc cuối cùng của Gene là thiết lập một nhóm các ứng dụng bằng chứng-cho-nội dung để hiển thị cho các nhóm khác có thể xây dựng các ứng dụng dựa trên đăng ký UDDI như thế nào.
Thiết lập
Bước đầu tiên trong khi làm việc với một đăng ký UDDI là phần mềm đăng ký của chính UDDI, nhưng Gene ngạc nhiên thích thú phát hiện ra rằng do tờ báo đang sử dụng Apache Geronimo làm máy chủ ứng dụng Web của mình, nên bước đó dễ dàng được Apache Geronimo quan tâm đến; Geronimo đi kèm với Apache jUDDI được cài đặt sẵn.
Điều đó đã được thực hiện, Gene phải quyết định cách anh ta thực sự sẽ truy cập vào đăng ký. Ở đây, Gene có hai sự lựa chọn. Sự lựa chọn đầu tiên là thực hiện đăng ký trực tiếp, sử dụng một UDDI dựa trên các API như một UDDI có trong jUDDI hoặc UDDI4J. Sự lựa chọn thứ hai là sử dụng một việc thực hiện JAXR (Java API cho Các đăng ký XML - Java API for XML Registries). JAXR được dự định để truy cập vào bất kỳ đăng ký nào, với sự hỗ trợ UDDI và ebXML là mục tiêu chính của nó.
Gene quyết định đi thẳng vào mã nguồn và tải UDDI4J. Nói cách khác, UDDI4J phụ thuộc vào một số các thư viện được phân phối cùng với Apache Axis, do đó Gene cũng tải Apache Axis. (Lưu ý rằng mặc dù các phần trước của dự án này đã sử dụng Axis2, UDDI4J phụ thuộc vào các thư viện phân phối cùng với Axis 1).
Việc thiết lập khá đơn giản, đòi hỏi Gene chỉ cần đảm bảo rằng tất cả các tệp UDDI4J và tệp Axis *. jar cần thiết có trên đường dẫn lớp (classpath) này. Xem Liệt kê 26.
Liệt kê 26. Việc thiết lập tập hợp
CLASSPATH=.; <UDDI4J_HOME>\lib\uddi4j.jar; <AXIS_HOME>\lib\axis.jar; <AXIS_HOME>\lib\saaj.jar; <AXIS_HOME>\lib\jaxrpc.jar; <AXIS_HOME>\lib\log4j-1.2.8.jar; <AXIS_HOME>\lib\commons-logging-1.0.4.jar; <AXIS_HOME>\lib\commons-discovery-0.2.jar;
Cuối cùng, Gene cần một tên người dùng và mật khẩu để kết nối đến đăng ký. Về mặt
này, mỗi đăng ký là khác nhau, vì vậy chúng ta sẽ không đi vào chi tiết. Việc cài đặt
mặc định của UDDI trong Apache Geronimo sử dụng một tên người dùng và mật khẩu là
"juddi".
Kết nối tới đăng ký
Bước đầu tiên trong bất kỳ ứng dụng nào là kết nối tới đăng ký. Xem Liệt kê 27.
Liệt kê 27. Kết nối tới đăng ký
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; public class CreateNewBusiness { public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); } catch(Exception e ) { e.printStackTrace(); } } }
Bắt đầu từ đầu, Gene thiết lập các giá trị khác nhau mà Gene sẽ cần trong suốt ứng
dụng. Cụ thể, Gene đặt tên lớp cho
TransportFactory.
UDDI4J có thể sử dụng số lượng bất kỳ của các lớp thích hợp, chẳng hạn như một lớp đi
kèm với Apache Axis, như bạn thấy ở đây, một lớp đi kèm với gói Apache SOAP cũ hoặc
bất cứ thứ gì tương tự.
Cuối cùng, Gene thiết lập các giá trị
inquiryURL và
publishURL cho đăng ký đó -- các giá trị này thường sẽ khác
nhau, một phần vì việc xuất bản luôn được thực hiện bằng cách sử dụng SSL -- và yêu
cầu một thẻ (token) ủy quyền.
Thẻ này rất quan trọng vì nó là cách mỗi yêu cầu biểu thị rằng nó đã được xác thực với máy chủ. Bởi vì mỗi đăng ký xử lý những thứ khác nhau, nên để duy trì việc gửi tên người dùng và mật khẩu với mỗi yêu cầu là không thực tế (hoặc an toàn).
Khi chạy ứng dụng này, Gene thấy một kết quả như sau:
Security
authToken:authToken:505A7DE0-D897-11DA-A5BF-ADFF17B378CF
Tạo một thực thể kinh doanh
Tiếp theo Gene muốn tạo một thực thể kinh doanh. Xem Liệt kê 28.
Liệt kê 28. Tạo
businessEntity
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import org.uddi4j.datatype.business.BusinessEntity; import org.uddi4j.response.BusinessDetail; import org.uddi4j.datatype.business.Contact; import org.uddi4j.datatype.business.Contacts; import org.uddi4j.util.KeyedReference; import org.uddi4j.util.IdentifierBag; import org.uddi4j.util.CategoryBag; import org.uddi4j.datatype.tmodel.TModel; import java.util.Vector; public class CreateNewBusiness { public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String businessName = "The Daily Moon"; String alt_businessName = "Daily Moon"; String contact_personName = "Pat Moonie"; String contact_phone = "212-555-1212"; String identifier_homepage = "http://www.daily-moon.com"; String category_NAICS = "511110"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); Vector entities = new Vector(); BusinessEntity newBusiness = new BusinessEntity("", businessName); Contact newContact = new Contact(contact_personName); Vector contactsVector = new Vector(); contactsVector.addElement(newContact); Contacts contacts = new Contacts(); contacts.setContactVector(contactsVector); newBusiness.setContacts(contacts); KeyedReference taxid = new KeyedReference(TModel.HOMEPAGE_TMODEL_KEY, identifier_homepage); IdentifierBag idBag = new IdentifierBag(); i dBag.add(taxid); newBusiness.setIdentifierBag(idBag); KeyedReference category = new KeyedReference(TModel.NAICS_TMODEL_KEY, category_NAICS); CategoryBag catBag = new CategoryBag(); catBag.add(category); entities.addElement(newBusiness); BusinessDetail bd = proxy.save_business(token.getAuthInfoString(), entities); Vector businessEntities = bd.getBusinessEntityVector(); BusinessEntity returnedBusinessEntity = (BusinessEntity) (businessEntities.elementAt(0)); System.out.println("The new businessKey:" + returnedBusinessEntity.getBusinessKey()); } catch(Exception e ) { e.printStackTrace(); } } }
Quá trình kết hợp một
businessEntity với nhau về cơ bản
bao gồm các phần tử xây dựng giống như chúng đang ở trong XML, với dạng "số nhiều"
(như
"contacts" (các liên hệ),
"tModelInfos" và v.v) được xử lý như các vectơ.
Trong trường hợp này, Gene xây dựng vector liên hệ
identifierBag và
categoryBag và thêm các vector
liên hệ này vào đối tượng
BusinessEntity. Đối tượng tự nó
được thêm vào một Vector, tức là các phương thức
save_business() này, cùng với thẻ uỷ quyền.
Kết quả là một đối tượng
BusinessDetail có chứa một hoặc
nhiều đối tượng
BusinessEntity khi các đối tượng này có
trong cơ sở dữ liệu. Trong trường hợp này, Gene gửi
BusinessEntity đi mà không cần một giá trị cho
businessKey, để cho đăng ký biết tạo một đối tượng mới và do đó tạo một
khóa mới. Bằng cách lấy
BusinessEntity đầu tiên từ vectơ,
sau đó Gene có thể có được một
businessKey mới.
Khi chạy ứng dụng này, Gene nhận được kết quả được hiển thị trong Liệt kê 29:
Liệt kê 29. Nhận được một businessKey mới
Security authToken:authToken:1D05DB90-D899-11DA-A5BF-D3513DE466CA The new businessKey:1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7
Tạo một giao diện dịch vụ
tModel
Với doanh nghiệp tại chỗ, tiếp theo Gene bắt đầu thêm giao diện dịch vụ. Xem Liệt kê 30.
Liệt kê 30. Tạo một
tModel
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector; import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.response.TModelDetail; import org.uddi4j.datatype.OverviewURL; import org.uddi4j.datatype.OverviewDoc; import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference; public class CreateNewInterface{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); Vector tModels = new Vector(); TModel tModel = new TModel("", "http://www.daily-moon.com/classifieds-interface"); tModel.setDefaultDescriptionString( "Interface for the Daily Moon Classified "+ "Department web application"); OverviewDoc overviewDoc = new OverviewDoc(); overviewDoc.setDefaultDescriptionString( "WSDL interface document"); OverviewURL overviewURL = new OverviewURL( "http://www.nicholaschase.com/ClassifiedsService-interface.wsdl"); overviewDoc.setOverviewURL(overviewURL); tModel.setOverviewDoc(overviewDoc); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); tModel.setCategoryBag(catBag); tModels.add(tModel); TModelDetail tModelDetail = proxy.save_tModel(token.getAuthInfoString(), tModels); Vector tModelVector = tModelDetail.getTModelVector(); TModel tModelReturned = (TModel)(tModelVector.elementAt(0)); System.out.println("TModel Saved: " + tModelReturned.getNameString()); System.out.println("TModel Key : " + tModelReturned.getTModelKey()); } catch(Exception e ) { e.printStackTrace(); } } }
Như trước, Gene bắt đầu tạo mô hình phần tử XML trong mã Java. Gene bắt đầu bằng cách
tạo
TModel, lại không có khóa để biểu thị rằng anh ta tạo
một đối tượng mới và thiết lập sự mô tả. Sau đó Gene tạo
OverviewDoc, bao gồm sự mô tả và
OverviewURL.
Tiếp theo, Gene tạo
KeyedReferences cho
CategoryBag. Lưu ý rằng Gene sẽ tham chiếu
tModels, cụ thể, vì thế Gene cung cấp
tModelKey cho mỗi một trong số chúng; giá trị này là tùy chọn. Cuối cùng,
Gene lưu
TModel, một lần nữa lấy ra đối tượng từ giá trị
được trả về.
Việc chạy ứng dụng cung cấp cho Gene kết quả được hiển thị trong Liệt kê 31:
Liệt kê 31. Nhận được một khóa tModel mới
Security authToken:authToken:3312DF20-D8A1-11DA-A5BF-D754085751C9 TModel Saved: http://www.daily-moon.com/classifieds-interface TModel Key : uuid:332F67D0-D8A1-11DA-A5BF-DF15F533BFA1
Tạo một dịch vụ
Tạo chính dịch vụ đó theo cùng thủ tục cơ bản. Xem Liệt kê 32.
Liệt kê 32. Tạo dịch vụ
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector; import org.uddi4j.datatype.business.BusinessEntity; import org.uddi4j.datatype.service.BusinessService; import org.uddi4j.datatype.binding.BindingTemplate; import org.uddi4j.datatype.binding.BindingTemplates; import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference; import org.uddi4j.datatype.binding.AccessPoint; import org.uddi4j.datatype.binding.TModelInstanceDetails; import org.uddi4j.datatype.binding.TModelInstanceInfo; import org.uddi4j.datatype.binding.InstanceDetails; import org.uddi4j.datatype.OverviewDoc; import org.uddi4j.datatype.OverviewURL; import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.response.ServiceDetail; public class CreateNewService{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String businessKey = "1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); BusinessService businessService = new BusinessService(""); businessService.setDefaultNameString( "ClassifiedService",null); businessService.setBusinessKey(businessKey); BindingTemplate bindingTemplate = new BindingTemplate(); AccessPoint accessPoint = new AccessPoint( "http://www.daily-moon.com:8080/axis2/services/ClassifiedService","http"); bindingTemplate.setAccessPoint(accessPoint); TModelInstanceDetails tModelDetails = new TModelInstanceDetails(); TModelInstanceInfo tModelInstanceInfo = new TModelInstanceInfo( "332F67D0-D8A1-11DA-A5BF-DF15F533BFA1"); InstanceDetails instanceDetails = new InstanceDetails(); OverviewDoc overviewDoc = new OverviewDoc(); OverviewURL overviewURL = new OverviewURL( "http://www.nicholaschase.com/ClassifiedService-impl.wsdl"); overviewDoc.setOverviewURL(overviewURL); instanceDetails.setOverviewDoc(overviewDoc); tModelInstanceInfo.setInstanceDetails(instanceDetails); tModelDetails.add(tModelInstanceInfo); bindingTemplate.setTModelInstanceDetails(tModelDetails); BindingTemplates bindingTemplates = new BindingTemplates(); bindingTemplates.add(bindingTemplate); businessService.setBindingTemplates(bindingTemplates); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); businessService.setCategoryBag(catBag); Vector services = new Vector(); services.addElement(businessService); ServiceDetail serviceDetail = proxy.save_service( token.getAuthInfoString(), services); Vector businessServices = serviceDetail.getBusinessServiceVector(); BusinessService businessServiceReturned = (BusinessService) (businessServices.elementAt(0)); String serviceKey = businessServiceReturned.getServiceKey(); System.out.println("The Name: "+ businessServiceReturned.getDefaultNameString()); System.out.println("The ServiceKey: "+ serviceKey); } catch(Exception e ) { e.printStackTrace(); } } }
Đến nay Gene đã thấy mô hình quen thuộc; tạo các đối tượng như chúng tồn tại trong
tài liệu XML. Hãy tạo
BusinessService và thêm
businessKey. Tạo
BindingTemplate,
bảo đảm tham chiếu
tModelKey được tạo khi Gene đã tạo giao
diện
tModel và URL cho tệp WSDL thực tế. Tạo
categoryBag thêm nó vào và lưu dịch vụ. Lấy ra dịch vụ và tên
và khóa của nó. Việc chạy ứng dụng đã cho Gene kết quả đầu ra được hiển thị trong Liệt kê 33.
Liệt kê 33. Lấy ra khóa tên dịch vụ
Security authToken:authToken:E4203390-D8A5-11DA-A5BF-8F6C6FEDFEBD The Name: ClassifiedService The ServiceKey: E43F2D40-D8A5-11DA-A5BF-880A3C83523B
Tìm một doanh nghiệp
Tiếp theo Gene xem xét hướng đưa các tìm kiếm đó vào hoạt động. Gene bắt đầu một tìm kiếm doanh nghiệp, cố gắng đảm bảo rằng tờ báo này đã được nhập vào đăng ký và người ta chưa sao chép nó. Xem Liệt kê 34.
Liệt kê 34. Tìm một doanh nghiệp
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector; import org.uddi4j.datatype.Name; import org.uddi4j.response.BusinessInfo; import org.uddi4j.response.BusinessList; import org.uddi4j.util.FindQualifier; import org.uddi4j.util.FindQualifiers; public class FindBusiness{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); String businessToFind = "The Daily Moon"; Vector names = new Vector(); names.add(new Name(businessToFind)); FindQualifiers findQualifiers = new FindQualifiers(); Vector qualifier = new Vector(); qualifier.add(new FindQualifier("exactNameMatch")); findQualifiers.setFindQualifierVector(qualifier); BusinessList businessList = proxy.find_business(names, null, null, null,null,findQualifiers,5); Vector businessInfoVector = businessList.getBusinessInfos().getBusinessInfoVector(); for( int i = 0; i < businessInfoVector.size(); i++ ){ BusinessInfo businessInfo = (BusinessInfo)businessInfoVector.elementAt(i); System.out.println(businessInfo.getDefaultNameString() + ": " + businessInfo.getBusinessKey()); } } catch(Exception e ) { e.printStackTrace(); } } }
Gene sẽ tìm kiếm một giá trị tên cụ thể, vì đó là kiểu tìm kiếm mà Gene xây dựng.
Gene tạo một
Vector của các đối tượng tên chỉ có một mục
và tạo một
FindQualifier để xác định rằng Gene chỉ tìm
kiếm một sự so khớp chính xác. Cuối cùng, Gene cung cấp yêu cầu cho phương thức
find_business(), để nhận các tên làm các tham số, bất kỳ
discoveryURLs nào, một
IdentifierBag,
CategoryBag,
TModelBag,
FindQualifiers bất kỳ và số lượng
tối đa của các kết quả để trả về.
Kết quả là một
BusinessList, thông qua đó Gene lặp đi lặp
lại để xem tất cả các giá trị của nó trong trường hợp thông tin được sao chép. Đối
với mỗi giá trị, Gene in tên và
businessKey như bạn thấy
trong Liệt kê 35.
Liệt kê 35. Tên doanh nghiệp và businessKey
Security authToken:authToken:DBEAE280-D8A8-11DA-A5BF-A6D55D3D237D The Daily Moon: 1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7 The Daily Moon: 1A3DB880-D5F4-11DA-B880-F94D3591C691
Trong trường hợp này, Gene có thể thấy rằng thông tin được sao chép, vì vậy Gene có
thể cung cấp
businessKey bổ sung cho phương thức
delete_business() của đối tượng
UDDIProxy .
Tìm một dịch vụ
Tiếp theo, Gene muốn đảm bảo có thể tìm thấy
ClassifiedService theo thể loại của nó. Xem Liệt kê
36.
Liệt kê 36. Tìm một kiểu dịch vụ
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector; import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference; import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.datatype.binding.BindingTemplate; import org.uddi4j.datatype.binding.TModelInstanceInfo; import org.uddi4j.datatype.binding.TModelInstanceDetails; import org.uddi4j.datatype.binding.AccessPoint; import org.uddi4j.datatype.binding.InstanceDetails; import org.uddi4j.datatype.service.BusinessService; import org.uddi4j.response.ServiceDetail; import org.uddi4j.response.ServiceInfo; import org.uddi4j.response.ServiceList; public class FindTypeOfService{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); ServiceList serviceList = proxy.find_service(null, null, catBag,null,null,5); Vector serviceInfoVector = serviceList.getServiceInfos().getServiceInfoVector(); for( int i = 0; i < serviceInfoVector.size(); i++ ){ ServiceInfo serviceInfo = (ServiceInfo)serviceInfoVector.elementAt(i); System.out.println("Service name: " + serviceInfo.getDefaultNameString()); System.out.println("Service key: " + serviceInfo.getServiceKey()); ServiceDetail serviceDetail = proxy.get_serviceDetail (serviceInfo.getServiceKey()); BusinessService thisService = (BusinessService)serviceDetail .getBusinessServiceVector().elementAt(0); if (thisService.getBindingTemplates().size() > 0){ BindingTemplate thisBinding = (BindingTemplate)thisService .getBindingTemplates().get(0); TModelInstanceDetails tModelDetails = thisBinding.getTModelInstanceDetails(); TModelInstanceInfo tModelInfo = tModelDetails.get(0); InstanceDetails instanceDetails = tModelInfo.getInstanceDetails(); String wsdlDocument = instanceDetails.getOverviewDoc() .getOverviewURLString(); System.out.println("Document located at " + wsdlDocument); } } } catch(Exception e ) { e.printStackTrace(); } } }
Bước đầu tiên của Gene là tạo một
CategoryBag cho phép
Gene tìm kiếm tất cả WSDL đã xác định các dịch vụ phải làm với các tờ báo. Kết quả
của việc tìm kiếm đó là một
ServiceList, thông qua đó Gene
lặp đi lặp lại để có thêm thông tin. Một đối tượng
ServiceInfo biểu thị từng dịch vụ trong kết quả và Gene kết nối qua mỗi
một trong số các dịch vụ, hiển thị tên và serviceKey của các dịch vụ
serviceKey.
Tuy nhiên, nếu Gene muốn biết thêm chi tiết, chẳng hạn như URL cho các tệp WSDL, Gene
phải sử dụng
serviceKey để yêu cầu
ServiceDetail cho dịch vụ đó.
ServiceDetail
không có hay có nhiều
BindingTemplates được liên kết với
nó và nếu Gene tìm thấy một BindingTemplate, Gene thực hiện cách của mình xuống dưới
thông qua đối tượng
TModelInstanceDetails tới đối tượng
InstanceDetails, trong đó bao gồm
OverviewDoc và vì thế gồm cả
OverviewURL. Kết
quả hiển thị không chỉ tên và
serviceKey của dịch vụ kết
quả, mà còn là URL mà người dùng có thể tìm thêm thông tin ở đó. Xem Liệt kê 37.
Liệt kê 37. Các kết quả cuối cùng
Security authToken:authToken:59FE37C0-D8AF-11DA-A5BF-A79333DB92F9 Service name: ClassifiedService Service key: E43F2D40-D8A5-11DA-A5BF-880A3C83523B Document located at http://www.nicholaschase.com/ClassifiedService-impl.wsdl
Tóm tắt
Một môi trường phân tán đòi hỏi một kho lưu trữ tập trung để những người dùng và các nhà phát triển biết cái gì có sẵn và nơi tìm nó và các dịch vụ Web không là ngoại lệ. Hướng dẫn này đã giải thích việc sử dụng UDDI, cung cấp một đăng ký thông tin về các doanh nghiệp và dịch vụ có sẵn.
Trong hướng dẫn này, bạn đã học:
- UDDI là gì và tại sao nó lại quan trọng.
- Làm thế nào để cấu trúc dữ liệu UDDI.
- Làm thế nào để phân biệt giữa các giao diện và các việc hiện thực SOAP.
- Làm thế nào để tìm dữ liệu trong một đăng ký UDDI.
- Làm thế nào để tương tác với một đăng ký UDDI bằng cách sử dụng Java.
Các phần tiếp theo của loạt bài này sẽ bàn về các nhu cầu an ninh ngày càng tăng, xem xét Các ứng dụng Web-an ninh (WS-Security) và Các ứng dụng Web-Chính sách (WS-Policy).
Tải về
Tài nguyên
Học tập
- Đọc các hướng dẫn khác trong loạt bài này.
- Truy cập trang UDDI.
- Bạn có thể tìm các đặc tả cho tất cả ba phiên bản, bao gồm các tài liệu lược đồ XML.
- Xem những thay đổi trong phiên bản UDDI 3.0 trong Bay đi xa hơn với UDDI V3 của Tom Bellwood.
- Đối với một loạt ba phần về các phương thức khác nhau sử dụng WSDL với các đăng ký UDDI, xem loạt bài của developerWorks "Hiểu biết về WSDL trong một đăng ký UDDI:"
- Đọc loạt bài trên developerWorks "Vai trò của các nút
UDDI riêng biệt trong các dịch vụ web:"
- Phần 1: Sáu loại UDDI (05.2001)
- Phần 2: Các nút riêng và các nút toán tử (05.2001)
- Đọc loạt bài năm phần "Một cách tiếp cận mới tới UDDI
và WSDL:"
- Phần 1: Giới thiệu về Chú giải kỹ thuật UDDI WSDL của OASIS mới (08.2003)
- Phần 2: Các câu hỏi được Chú giải kỹ thuật UDDI WSDL của OASIS mới hỗ trợ (09.2003)
- Phần 3: Một ví dụ về Chú giải kỹ thuật UDDI WSDL của OASIS mới đang hoạt động (10.2003)
- Phần 4: Xuất bản từ Java bằng cách sử dụng Chú giải kỹ thuật UDDI WSDL của OASIS mới (03.2004)
- Phần 5: Truy vấn từ một ứng dụng Java bằng cách sử dụng Chú giải kỹ thuật UDDI WSDL của OASIS mới (11.2004)
- Tìm hiểu thêm về UDDI4J: UDDI4J: Kết hợp với các dịch vụ Web.
- Xem: Programming with UDDI4J version 2 (developerWorks, 07. 2002) với một bài viết thảo luận về tính lặp lại tiếp theo của API khách của UDDI, UDDI4J v2,
Lấy sản phẩm và công nghệ
- Tải Apache Geronimo.
- Để tạo đăng ký UDDI riêng của bạn, tải Apache jUDDI.
- Tải UDDI4J.
- Tải Apache Axis 1.3.
- Tải Java 1.4.2. Geronimo sẽ không chạy đúng với Java 1.5.
- UDDI4Py là gói Python cho phép gửi các yêu cầu đến và xử lý các đáp ứng từ các API phiên bản 2 của UDDI.
Thảo luận
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Trước khi bạn bắt đầu
Hướng dẫn này giải thích giao diện khám phá và mô tả thống nhất hoặc UDDI (Uniform Description and Discovery Interface). UDDI xác định một đăng ký của các dịch vụ Web và thông tin công ty khác và được thiết kế để cung cấp một cách khám phá các dịch vụ Web mới để sử dụng và trong các trường hợp lý tưởng, tự động hoá việc sử dụng chúng.
Hướng dẫn này giả định rằng bạn đã quen thuộc với các khái niệm chung của các dịch vụ Web, cũng như SOAP. Kiến thức về WSDL cũng có ích, nhưng hướng dẫn này chỉ xem xét lại các khái niệm nói chung.
Để làm theo cùng các mã trong phần cuối, bạn nên hiểu rõ về Java, nhưng các khái niệm, như phần còn lại của hướng dẫn, áp dụng cho bất kỳ ngôn ngữ lập trình nào.
### Về loạt bài này
Loạt bài hướng dẫn này dạy các khái niệm cơ bản về các dịch vụ Web bằng cách tiếp tục
khai thác về tờ báo hư cấu,
*Daily Moon* (Mặt trăng hàng ngày), như là các nhân
viên sử dụng các dịch vụ Web để tạo ra một hệ thống tiến trình công việc để tăng năng
suất khi có nhiều thay đổi.
Phần 1 đã giải thích các khái niệm cơ bản sau các dịch vụ Web và đã hiển thị cách sử dụng SOAP, đặc tả này làm cơ sở cho hầu hết những gì sắp tới, kết nối phòng chuyên mục rao vặt với Hệ thống quản lý nội dung.
Phần 2, đưa mọi thứ tiến một bước xa hơn, khi giải thích cách sử dụng WSDL (Web Services Description Language - Ngôn ngữ mô tả các dịch vụ Web) để định nghĩa các thông báo được tạo với những thứ mà người ta hy vọng ở dịch vụ Web, cho phép nhóm làm việc tạo các dịch vụ và các ứng dụng khách kết nối với các thông báo dễ dàng hơn.
Phần 3 tìm nhóm làm việc có một số dịch vụ tại chỗ và có một mong muốn định vị các dịch vụ dễ dàng. Đáp lại, UDDI (Universal Description, Discovery and Integration - Tích hợp, khám phá và mô tả đa năng) cung cấp một đăng ký có thể tìm kiếm được của các dịch vụ có sẵn bằng cách đưa ra công khai các dịch vụ riêng của chúng cho những người khác.
Phần 4 và 5, Các dịch vụ Web-An ninh (WS-Security) và Các dịch vụ Web-Chính sách (WS-Policy), tìm nhóm làm việc có mục tiêu là bảo vệ của các dịch vụ của tờ báo và những thay đổi mà các nhóm làm việc cần phải thực hiện để truy cập các dịch vụ mới được bảo vệ đó.
Tính tương thích là từ khóa trong phần 6, do các dịch vụ từ những sự hiện thực khác nhau phải được truy cập từ một hệ thống duy nhất. Phần 6 trình bày các yêu cầu và các thử nghiệm liên quan đến việc cấp chứng chỉ Các dịch vụ Web-Tính tương thích (WS-I).
Cuối cùng, phần 7 cho thấy cách sử dụng WS-BPEL (Ngôn ngữ thực hiện qui trình kinh doanh) để tạo các ứng dụng phức tạp từ các dịch vụ riêng biệt.
Bây giờ hãy xem xét hướng dẫn này trình bày những gì cụ thể hơn một chút.
### Về hướng dẫn này
[Phần 1 của loạt bài này](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services1/index.html) giới thiệu cho bạn các dịch vụ Web và nhấn mạnh tầm
quan trọng của SOAP. Chúng tôi đã làm điều này thông qua việc khai thác của một phòng
chuyên mục rao vặt của tờ báo hư cấu Daily Moon. Trong [Phần 2 của loạt bài này](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services2/index.html), phòng chuyên mục rao vặt quyết định tạo ra một dịch
vụ Web của riêng mình, tạo tài liệu sử dụng của mình bằng WSDL (Ngôn ngữ mô tả các
dịch vụ Web). Ở đây trong Phần 3, về các dịch vụ Web chủ báo đã quyết định đưa tất cả
ra khỏi các dịch vụ và đã yêu cầu sử dụng một đăng ký UDDI để theo dõi tất cả các
dịch vụ có sẵn.
Trong tiến trình hướng dẫn này, bạn sẽ học:
- UDDI là gì.
- UDDI dành cho cái gì.
- Cấu trúc của dữ liệu UDDI.
- Làm thế nào để biểu diễn có hiệu quả WSDL khi sử dụng UDDI.
- Các hoạt động mà bạn có thể thực hiện trên dữ liệu UDDI.
- Tương tác với một đăng ký UDDI bằng cách sử dụng Java.
### Điều kiện cần trước
Để làm theo cùng với các mã cho hướng dẫn này, bạn sẽ cần có sẵn phần mềm sau đây:
Thực hiện Apache Geronimo hay thực hiện một UDDI khác. Để làm theo cùng với các mã,
bạn sẽ cần truy cập vào một đăng ký UDDI. Đến cuối hướng dẫn, kiểu đăng ký nào mà bạn
sử dụng không quan trọng, do UDDI về cơ bản là một dịch vụ Web và cần được truy cập
từ nền tảng hay ngôn ngữ bất kỳ, tới nền tảng hoặc ngôn ngữ bất kỳ khác. Điều đó nói
rằng, các máy chủ ứng dụng Apache Geronimo cũng là cơ sở cho IBM Community Edition
(Ấn bản cộng đồng của WebSphere của IBM) và chúng tôi đã sử dụng máy chủ đó trong
Phần 1 và 2 của loạt bài này, có thực hiện đăng ký UDDI của Apache, jUDDI, được cài
đặt sẵn và cấu hình như là một phần của một cài đặt tiêu chuẩn. Bạn có thể tải
[Apache Geronimo](http://geronimo.apache.org/downloads.html) từ
Apache.org. Để biết thêm thông tin về cài đặt Geronimo, xem [Phần 1](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services1/index.html) của loạt bài này.
UDDI4J -- Để truy cập đăng ký, hướng dẫn này giải thích việc sử dụng dự án UDDI4J,
cung cấp một sự tích hợp khá chặt chẽ giữa các khái niệm UDDI và mã Java. Bạn có thể
tải
[UDDI4J](http://sourceforge.net/projects/uddi4j/) từ
Sourceforge.net.
Apache Axis2 hoặc việc thực hiện SOAP khác -- Bạn có thể tạo các thông báo SOAP bằng
tay và bạn có thể giải thích chúng bằng tay, nhưng thật thoải mái để có một sự thực
hiện có ích. Bạn sẽ sử dụng Apache Axis2, bao gồm các việc thực hiện của các API có
liên quan đến-SOAP khác nhau để làm cho cuộc sống của bạn dễ dàng hơn đáng kể. Bạn có
thể tải
[Apache Axis2 ](http://ws.apache.org/axis2/download.cgi) từ
Apache.org. Hướng dẫn này sử dụng phiên bản 0.94, nhưng phiên bản mới hơn cũng sẽ
hoạt động.
Ấn bản tiêu chuẩn Java 2 phiên bản 1.4 -- Tất cả mọi thứ trong các công cụ này dựa
trên Java, như là các dịch vụ và các ứng dụng khách mà bạn sẽ xây dựng trong hướng
dẫn này. Bạn có thể tải
[J2SE
SDK](http://java.sun.com/j2se/1.4.2/download.html) từ Sun Developer Network. Geronimo sẽ không chạy đúng với Java 1.5.
Bạn cũng sẽ cần một trình duyệt Web và một trình soạn thảo văn bản, nhưng tôi chắc chắn rằng bạn đã có chúng rồi. Nếu bạn muốn, bạn cũng có thể sử dụng một IDE như Eclipse, nhưng do chúng ta đang tập trung vào các công nghệ hơn là các công cụ, nên chúng ta sẽ chỉ sử dụng một trình soạn thảo văn bản và dòng lệnh để chỉnh sửa các tệp của chúng ta và biên dịch chúng.
## Tổng quan
Chúng ta hãy nhìn vào nơi chúng ta ở đó cho đến nay.
### Câu chuyện cho đến nay
Loạt bài này cho phép các nhân viên của tờ báo hư cấu
*Daily Moon* khi tờ báo
này chuyển nhiều hoạt động hàng ngày của mình sang một hệ thống dựa trên các dịch vụ
Web. Trong Phần 1, Phòng chuyên mục rao vặt tìm hiểu về SOAP bằng cách tương tác với
Hệ thống quản lý nội dung và trong Phần 2, họ đã tạo dịch vụ riêng của mình và đã
định nghĩa nó bằng cách sử dụng WSDL. Bây giờ Rudy, chủ báo, bị ấn tượng với cách mà
các dịch vụ Web đang làm việc trong tổ chức của mình đến mức ông muốn nhìn thấy các
dịch vụ Web được sử dụng thường xuyên hơn, thậm chí đến mức tương tác với các tổ chức
khác.
Cuối cùng, ông đã yêu cầu hai thành viên của nhóm Công nghệ thông tin, Gene và Francis, tạo một đăng ký dịch vụ Web, mà ông hy vọng sẽ cho phép các phòng khác dễ dàng tìm thấy những gì họ cần để chuyển các hoạt động của họ qua các dịch vụ Web.
Hai nhân viên này quyết định cách tốt nhất để làm điều đó sẽ là triển khai thực hiện một đăng ký của giao diện UDDI. Đăng ký này sẽ cho phép họ không chỉ lưu thông tin trên các dịch vụ riêng của tờ báo, mà nó cũng có thể tương tác với các đăng ký tại các tờ báo khác.
### Trình làm mới WSDL
Một phần của quá trình đăng ký một dịch vụ với một đăng ký UDDI bao gồm việc thao tác
định nghĩa WSDL, vì vậy trước khi chuyển sang dự án mới, Gene xem xét lại các khái
niệm cơ bản của WSDL bằng cách quay lại qua các tệp được tạo ra trong dự án sau cùng
của mình. Xem
[Liệt kê 1](#listing1).
##### Liệt kê 1. Các tệp WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.daily-moon.com/classifieds" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace="http://www.daily-moon.com/classifieds"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://org.apache.axis2/xsd" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:element name="createNewAdRequest"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="content" /> <xs:element type="xs:string" name="endDate" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="createNewAdResponse"> <xs:complexType> <xs:sequence> <xs:element type="xs:int" name="newAdId" /> </xs:sequence> </xs:complexType> </xs:element> ... </xs:schema> </wsdl:types> <wsdl:message name="createNewAdRequestMessage"> <wsdl:part name="part1" element="ns1:createNewAdRequest" /> </wsdl:message> <wsdl:message name="createNewAdResponseMessage"> <wsdl:part name="part1" element="ns1:createNewAdResponse" /> </wsdl:message> <wsdl:message name="getExistingAdsResponseMessage"> ... </wsdl:message> <wsdl:portType name="ClassifiedServicePortType"> <wsdl:operation name="createNewAd"> <wsdl:input message="tns:createNewAdRequestMessage" /> <wsdl:output message="tns:createNewAdResponseMessage" /> </wsdl:operation> <wsdl:operation name="finalizeIssue">...</wsdl:operation> <wsdl:operation name="editExistingAd">...</wsdl:operation> <wsdl:operation name="getExistingAds">...</wsdl:operation> </wsdl:portType> <wsdl:binding name="ClassifiedServiceBinding" type="tns:ClassifiedServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <wsdl:operation name="createNewAd"> <soap:operation soapAction="createNewAd" style="document" /> <wsdl:input> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="finalizeIssue">...</wsdl:operation> <wsdl:operation name="editExistingAd">...</wsdl:operation> <wsdl:operation name="getExistingAds">...</wsdl:operation> </wsdl:binding> <wsdl:service name="ClassifiedService"> <wsdl:port name="ClassifiedServicePort" binding="tns:ClassifiedServiceBinding"> <soap:address location= "http://www.daily-moon.com:8080/axis2/services/ClassifiedService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Chúng tôi đã gỡ bỏ một số đoạn trong tài liệu này vì các lý do không gian của bài viết này, nhưng chúng ta hãy xem lại các khái niệm chung.
Bắt đầu từ phía dưới cùng, chúng ta có dịch vụ thực tế, có sẵn tại một vị trí cụ thể
và triển khai thực hiện giao diện
ClassifiedServiceBinding. Người ta đã biểu thị giao diện đó như là một ràng
buộc, chỉ rõ các hoạt động được quy định trong portType
ClassifiedServicePortType.
portType định nghĩa
các thông báo nhập vào và xuất ra bằng cách sử dụng các phần tử được quy định trong
phần các kiểu.
Một ứng dụng khách XML có thể đọc thông tin này và sử dụng nó để truy cập vào dịch vụ Web. (Hoặc chính xác hơn, một công cụ tạo ứng dụng khách của dịch vụ Web có thể đọc thông tin này và tạo một ứng dụng khách có thể truy cập vào dịch vụ Web).
### Từ đây chúng ta đi đâu
Trong tiến trình hướng dẫn này, Gene và Francis sẽ tách thông tin của tờ báo
*Daily
Moon* thành các cấu trúc thân thiện-UDDI, bao gồm thông tin nghiệp vụ và thông
tin dịch vụ. Họ sẽ sử dụng nó để nhập các thông tin và các dịch vụ của tờ báo vào một
đăng ký UDDI bằng cách sử dụng UDDI4J. Họ cũng sẽ làm việc với đăng ký riêng của một
tờ báo khác, tờ *Daily Star*, để tìm kiếm một dịch vụ cung cấp điểm số của các
môn thể thao đang diễn ra.
Bây giờ hãy xem tất cả mọi thứ về UDDI.
## Giới thiệu về UDDI
UDDI về cơ bản là một dịch vụ Web, nhưng UDDI rất khác so với SOAP và WSDL nên để hiểu được một nền tảng nhỏ trước khi chúng ta bắt đầu là rất tốt.
### Tại sao là UDDI?
Khi tất cả các ứng dụng là cục bộ, thật khá dễ dàng để tìm những gì bạn muốn. Tuy nhiên, khi bạn có một hệ thống phân tán như các dịch vụ Web, bạn không có lợi ích gì về việc có một kho lưu trữ trung tâm nữa. Hệ thống phân tán cũng dễ bị thay đổi. Đây là thế giới trong đó UDDI hình thành. UDDI được dự định để phục vụ hai mục đích. Theo sự tạo hình ban đầu của mình, UDDI đã được diễn đạt như là một loại "Đăng ký doanh nghiệp đa năng" (Universal Business Registry). Ý tưởng là điều mà các doanh nghiệp có thể tìm kiếm các đối tác bằng cách sử dụng một trong ba phương pháp sau:
- "Các trang trắng": Các trang trắng giống như các trang trắng của danh bạ điện thoại, trong đó người ta có thể tìm kiếm thông tin về một công ty. Ví dụ, nếu bạn đã biết tên của công ty, bạn có thể tìm ra công ty đó ở đâu, cách để liên hệ với họ và thậm chí cả liên hệ với ai trong tổ chức đó.
- "Các trang vàng": Các trang vàng, cũng vậy, giống như các trang trắng của danh bạ điện thoại, trong đó bạn có thể tra cứu các doanh nghiệp dựa trên sự phân loại. UDDI đã quy định các sự phân loại khác nhau mà các công ty có thể sử dụng để phân loại chính mình. Ví dụ, nếu bạn đang tìm kiếm các đồ thể thao, bạn có thể tìm các công ty có một mã số của hệ thống phân loại công nghiệp Bắc Mỹ (NAICS) là 339.920.
- "Các trang xanh": Đúng, không có các trang xanh lá cây trong danh bạ điện thoại của bạn, nhưng ý tưởng là ở chỗ các công ty có thể sử dụng phương pháp tìm kiếm này để tìm các đối tác thương mại đã triển khai thực hiện một dịch vụ cụ thể. Ví dụ, bạn có thể thực hiện tìm kiếm các công ty triển khai thực hiện một tính toán từ xa bằng cách sử dụng các mã bưu điện (zip).
Người ta cũng nghĩ UDDI như là một cách để giữ cho các ứng dụng phân tán hoạt động trong thời gian dài. Ý tưởng là bạn sẽ nhớ nhanh thông tin về cách truy cập một dịch vụ cụ thể và nếu khách hàng của bạn bị ngắt, ứng dụng sẽ tự động quay trở về chỗ đăng ký và kiểm tra để xem các thông tin đã thay đổi chưa. Nếu nó đã thay đổi, bạn có thể chỉ cần tạo các thay đổi trong ứng dụng của bạn (một cách tự động, trong một thế giới lý tưởng) và thử lại yêu cầu của bạn.
### UDDI trong thế giới thực
Khi đang tìm kiếm một UBR (Đăng ký doanh nghiệp đa năng), Francis đã phát hiện ra rằng UBR đã không còn tồn tại nữa. Trong thực tế, các nhà tài trợ cho công ty của nó đã ngừng UBR khi UDDI phiên bản 3.0 được phát hành. Tại sao? Đúng, bất kể ý tưởng UBR đã là tốt như thế nào, thực tế là hầu như không ai sử dụng nó. Lý do gồm hai phần: đầu tiên, đã có rất ít thông tin có ích trong UBR -- trừ khi, đó là, bạn đang tìm kiếm một dịch vụ về số lượng cổ phiếu được bán ra tại thị trường chứng khoán, trong trường hợp này bạn có thể tìm thấy khá phong phú. Lý do thứ hai là các công ty, theo quy luật, không thực hiện kinh doanh với các tổ chức mà họ không hiểu rõ. Rất ít các tổ chức, nếu có, sẽ thực hiện một sự tìm kiếm tự động đối với các đối tác thương mại và sau đó mở hệ thống của họ cho các đối tác đó mà không có một chút chú trọng thích hợp nào. Vì vậy mô hình tìm kiếm tự động và gọi ra đã không thực sự cất cánh.
Mô hình đó cũng bị cản trở bởi thực tế là UDDI đã đi trước thời của nó, theo một số cách. Được thiết kế để xử lý tất cả các kiểu dịch vụ và không chỉ SOAP trên HTTP, UDDI không thêm ngay chính mình vào việc sử dụng các định nghĩa WSDL, ít nhất là trong khung nhìn của những thứ đang cố gắng sử dụng UDDI.
Tuy nhiên, điều đó không nói rằng UDDI không còn được sử dụng chút nào nữa. Thay vào đó, trên thực tế nó đang được sử dụng như một "đăng ký riêng" nhiều hơn. Các công ty tạo các đăng ký riêng của mình và nhập vào các dịch vụ riêng của mình. UDDI cũng có thể được sử dụng và là một kiểu đăng ký kinh doanh bên trong, theo cách mà từ đó người ta sử dụng LDAP theo truyền thống.
Hơn nữa, khi chúng ta chuyển qua một cách suy nghĩ "chỉ có dịch vụ Web" nhiều hơn về một ý tưởng SOA (Kiến trúc hướng dịch vụ), khả năng để xử lý nhiều hơn chỉ có mình SOAP có thể chỉ chứng tỏ bản thân nó khi chạy lâu dài.
### Cấu trúc dữ liệu UDDI
Thông tin được chứa trong một đăng ký UDDI bao gồm năm kiểu khác nhau:
businessEntityhoặc tổ chức công ty thực tế. Điều này có thể có nghĩa là toàn bộ tổ chức hoặc nó có thể là một tổ chức liên kết hoặc chi nhánh.
publisherAssertionhoặc mối quan hệ giữa
businessEntities. Để hợp lệ
publisherAssertionsphải được cả hai bên yêu cầu (vì vậy tôi không thể yêu cầu là một chi nhánh của một công ty khác), trừ khi cả hai thực thể có trách nhiệm với chủ báo hoặc trừ khi cả hai thực thể được nhập vào trong đăng ký bằng một tài khoản người dùng giống nhau.
bindingTemplate, về cơ bản là đặc tả của một giao diện của một dịch vụ. Nhiều businessServices có thể thực hiện
businessServices.
businessServicehay một dịch vụ do một doanh nghiệp cung cấp. Bây giờ, điều đó có vẻ đơn giản, nhưng trong thế giới của UDDI, điều đó không nhất thiết có nghĩa là nó là một dịch vụ Web. Ví dụ, bạn thực sự có thể xác định dịch vụ hỗ trợ điện thoại của doanh nghiệp của bạn (có nghĩa là số điện thoại thực tế mà người dùng quay số và tất cả mọi thứ mà đi kèm với nó) như một dịch vụ UDDI. Tất nhiên, bạn sẽ không có một tài liệu WSDL giả, nhưng nó sẽ là một dịch vụ được doanh nghiệp của bạn cung cấp.
tModelshoặc các mô hình siêu dữ liệu. Khi nghiên cứu UDDI, Francis đi đến kết luận rằng tModel có lẽ là lý do lớn nhất tại sao UDDI đã không cất cánh như mong đợi. Như một đăng ký của các dịch vụ, bạn sẽ mong đợi tìm thấy một cách để trực tiếp xác định giao diện cho một dịch vụ, như WSDL thực hiện. Nhưng, như đã nói, UDDI đã chưa bao giờ được dự định là độc quyền về các dịch vụ Web và được thiết kế với linh hoạt hơn nữa.
tModelsthực hiện trợ giúp trỏ đến các tài liệu XML, như chúng ta sẽ thấy sau này, nhưng trong thực tế chúng có nghĩa là một cách tổng quát để xác định thông tin về thứ gì đó, thông qua dịch vụ, một doanh nghiệp hay bất cứ điều gì khác.
Đó là những cấu trúc dữ liệu cơ bản của UDDI. Bây giờ hãy xem và cách thức trong đó UDDI nói chúng ta có thể tương tác với chúng.
### API của UDDI
UDDI nổi danh là quá phức tạp, nhưng với cốt lõi của mình UDDI thuộc về năm kiểu dữ
liệu được mô tả ở trên, được kết hợp với bốn hoạt động:
**tìm kiếm**, **nhận**,
**lưu** và **xóa**. Nói cách khác, đặc tả UDDI lưu ý những điều sau đây để
bạn có thể thực hiện với dữ liệu:
find_xx: Những phương thức này, chẳng hạn như
find_businessEntity,
find_businessServicevà v.v, cung cấp một cách để bạn tìm kiếm một bản ghi trong đăng ký UDDI. Những phương thức này trả về khóa để nhận dạng đối tượng.
get_xx: Một khi bạn có khóa duy nhất nhận dạng một đối tượng, bạn có thể sử dụng
get_xx methods, như
get_businessServicevà v.v, để lấy ra chính đối tượng thực tế đó. Ví dụ,
get_businessServicetrả về toàn bộ đối tượng
businessService, từ đó bạn thu được bất kỳ thông tin nào mà bạn cần.
save_xx: Như bạn có thể đã đoán được, các phương thức này thêm thông tin vào cơ sở dữ liệu hoặc chúng thay đổi thông tin đã có trong cơ sở dữ liệu.
delete_xx: Những phương thức này, chẳng hạn như
delete_bindingTemplate,
delete_tModel, và v.v, lấy khóa duy nhất của đối tượng làm tham số và loại bỏ nó khỏi cơ sở dữ liệu. Hành vi thực tế của các phương thức này phụ thuộc vào những gì bạn đang xóa. Ví dụ, vì
tModelsthường xuyên được các đối tượng khác trong cơ sở dữ liệu tham chiếu, nên chúng có thể không thực sự bị xóa; để thay thế người ta ẩn chúng đi
Hầu như tất cả mọi thứ của UDDI dựa trên 20 phân cắt giữa năm đối tượng (
businessService,
bindingTemplate,
publisherAssertion,
businessEntity và
tModel) và bốn hành động
(
find,
get,
save và
delete).
Bây giờ hãy xem cấu trúc này thực sự trông giống như thế nào.
## Cấu trúc dữ liệu UDDI
Để bắt đầu quá trình thêm công ty vào một đăng ký UDDI, Francis đã định nghĩa thông tin để nhập vào đăng ký đó.
businessEntity
Bước đầu tiên là nhập chính tờ báo đó vào đăng ký. Để làm điều này, Francis tạo một
đối tượng
businessEntity. Đối tượng này chứa thông tin về
doanh nghiệp, vừa để xác định doanh nghiệp và vừa để cung cấp thông tin về doanh
nghiệp. Ví dụ, đối tượng businessEntity có nhiều hơn một tên, (cho phép bạn, ít nhất
là, tạo một phần tử tên cho mỗi ngôn ngữ trong đó công ty được thể hiện), thông tin
liên hệ (người ta bảo Francis thêm Pat Mooney làm liên hệ chính), các dịch vụ liên
kết với các thực thể (Gene sẽ làm sau) và thông tin để nhận dạng và phân loại công
ty.
Mặc dù hầu hết mọi người sẽ không bao giờ tương tác với Đăng ký của UDDI (UDDI
Registry) theo cách này, thực tế là về cơ bản UDDI là một ứng dụng SOAP; tất cả các
hoạt động mà bạn thực hiện xảy ra như là kết quả của các thông báo SOAP được chuyển
qua lại. Điều này có nghĩa là businessEntity do Francis đang tạo ra cuối cùng được
biểu diễn như một phần tử XML. Xem
[Liệt kê 2](#listing2).
##### Liệt kê 2. Phần tử
businessEntity
<businessEntity businessKey="{uuid}"operator="(optional)" authorizedName="(optional)"> <discoveryURLs> <discoveryURL></discoveryURL> <discoveryURL></discoveryURL> </discoveryURLs> <name>The Daily Moon</name><name lang="fr-ca">La Lune Quotidienne</name> <description></description> <contacts> <contact> <description></description> <personName>Pat Mooney</personName> <phone></phone> <email>patm@daily-moon.com</email> <address useType="optional, billing, etc." sortCode="optional" tModelKey="optional"> <addressLine></addressLine> <addressLine></addressLine> <addressLine></addressLine> </address> </contact> <contact> ... </contact> </contacts> <businessServices> <businessService serviceKey="required" businessKey="optional"> ... </businessService> </businessServices> <identifierBag> ... </identifierBag> <categoryBag> ... </categoryBag> </businessEntity>
Một bản ghi
businessEntity thực hiện phải không quá phức
tạp. Trong thực tế, chỉ có một tên duy nhất và trình nhận dạng duy nhất để hoạt động
như là
businessKey (Khóa doanh nghiệp) cần thiết. Tuy
nhiên, để cho đầy đủ, tôi đã bao gồm toàn bộ cấu trúc, trừ một số đoạn bị cắt mà
chúng tôi sẽ nói về chúng sau đây. Trong một môi trường sản xuất các phần tử rỗng cần
được gỡ bỏ.
Hãy xem xét một số thông tin ở đây.
Bắt đầu từ trên cùng, một lần nữa,
businessKey, là một
trình nhận dạng. Toán tử và các thuộc tính
authorizedName
được ứng dụng đăng ký xử lý nội bộ, bạn không cần phải chạm vào chúng, nhưng chúng
đại diện cho thực thể chạy ứng dụng đăng ký đó và người hoặc tài khoản mà người nào
đó đã thêm vào bản ghi.
discoveryURLs được thêm vào đăng ký mỗi khi một
businessEntity được lưu vào đăng ký. Các URL này có nghĩa là một vị trí mà người sử
dụng có thể đi tới đó để có thêm nhiều thông tin về
businessEntity này.
Lưu ý là Francis đã thêm một tên bổ sung khác, biểu thị tên của tờ báo bằng tiếng
Pháp, ở đây tờ báo này đang cố gắng quảng cáo rùm beng để lôi kéo doanh nghiệp. Mỗi
một trong số những thực thể này mang thuộc tính
lang xác
định mã cho ngôn ngữ đang nói đến. Bạn có thể cung cấp các tên thay thế từ các chữ
viết tắt phổ biến, ví dụ, IBM thay cho International Business Machines.
Mô tả tùy chọn sắp tới chỉ là một chuỗi văn bản. Trong thực tế, hầu hết các phần tử chính trong UDDI có một mô tả tùy chọn.
Tiếp theo, Francis có thể thêm nhiều mối liên hệ hơn nữa. Đối với mỗi liên hệ anh ta
có thể xác định nhiều hay ít thông tin khi cần thiết
personName thường được cung cấp, nhưng các thông tin như số điện thoại,
e-mail và v.v được cung cấp dựa trên ý muốn của những người có liên quan, do tất cả
các thông tin trong Đăng ký UDDI (Registry UDDI) là công khai cho tất cả người dùng.
Các liên hệ cũng có thể có một địa chỉ, với
useType quy
định cụ thể loại địa chỉ. Ví dụ, trong trường hợp của một mối liên hệ, thông tin có
thể là địa chỉ nhà so với thông tin công việc và v.v. Trong trường hợp của một công
ty,
useType có thể là văn phòng chính, trung tâm phân phối
và v.v.
Phần tử
businessServices liệt kê các dịch vụ bất kỳ đã
được liên kết với
businessEntity này. Vì Gene vẫn chưa
thêm bất kỳ các dịch vụ nào, nên phần tử này thường vẫn rỗng. Hai mục cuối cùng,
identifierBag và
categoryBag, cung cấp thêm thông tin về chính công ty đó và được sử dụng
trong tìm kiếm. Chúng ta sẽ xem xét từng thứ trong chúng ngay sau đây.
publisherAssertion
Một
publisherAssertion là một câu lệnh về mối quan hệ của
một
businessEntity này với một businessEntity khác. Ví dụ,
Francis biết rằng một trong những mục tiêu của dự án này là sử dụng một dịch vụ được
cung cấp trong tờ báo Daily Star, trong đó tờ Daily Star cung cấp các điểm số của các
môn thể thao cho tờ
*Daily Moon*. Điều đó khiến cho tờ *Daily Star* trở
thành một nhà cung cấp nội dung cho tờ *Daily Moon*.Francis có thể biểu thị điều
đó như thể hiện trong [Liệt kê 3](#listing3).
##### Liệt kê 3.
publisherAssertion
<publisherAssertion> <fromKey>(businessKey for Daily Star)</fromKey> <toKey>(businessKey for Daily Moon)</toKey> <keyedReference tModelKey="904BD800-D53A-11DA-B055-850A1DA99D79" keyName="optional" keyValue="CONTENTPROVIDER" /> </publisherAssertion>
Các phần tử
fromKey và
toKey
biểu thị các mã nhận dạng (ID) duy nhất cho hai thực thể có liên quan. Trong trường
hợp này, đó là tờ
*Daily Moon* và tờ *Daily Star*. Tờ *Daily Star* là
nhà cung cấp nội dung cho tờ *Daily Moon*, do đó, các khóa được đặt cho phù hợp.
Chúng ta sẽ thấy
keyedReference (Tham chiếu có khóa) nhiều
lần. Trong trường hợp này, chúng ta sẽ nói rằng chính tham chiếu đó là một nhà cung
cấp nội dung.
keyValue (Giá trị khóa) là thuộc tính duy
nhất cần thiết cho một
keyedReference, nhưng cũng bình
thường để bao gồm một
keyName (Tên khóa) cho dễ đọc và một
tModelKey để nhận dạng một kiểu tham chiếu cụ thể.
Trong trường hợp này
tModelKey biểu thị cho vùng tên của
các hiệp hội giữa các tờ báo đối lập với các đại diện bên trong. Một lát nữa chúng ta
sẽ nói thêm về
tModels.
businessService
Tiếp theo, Francis cần nhập thông tin về các dịch vụ thực tế bất kỳ mà tờ Daily Moon
sắp cung cấp. Một đối tượng
businessService chứa hai mẩu
thông tin chính ngoài
serviceKey duy nhất cần thiết và
tên. Chúng là
bindingTemplates và bất kỳ các thể loại nào
mà dịch vụ này thuộc về chúng. Xem
[Liệt kê 4](#listing4).
##### Liệt kê 4.
businessService
<businessService serviceKey="required"businessKey="optional"> <name></name> <description></description> <bindingTemplates> <bindingTemplate serviceKey="optional" bindingKey="required"> ... </bindingTemplate> </bindingTemplates> <categoryBag> ... </categoryBag> </businessService>
BindingTemplate
Tmodelinstancedetails là một sự biểu thị về nó tương thích
với những ứng dụng hoặc các đặc tả nào. Xem
[Liệt kê 5](#listing5).
##### Liệt kê 5. The
bindingTemplate
Một
bindingTemplate là thứ định nghĩa cả nơi người ta có
thể tìm thấy dịch vụ lẫn dịch vụ này làm gì, nghe có vẻ đơn giản. Tuy nhiên, cả hai
hàm này đảm nhận ý nghĩa mới trong nội dung của UDDI. Ví dụ, để xác định có thể truy
cập một dịch vụ ở đâu, bạn có thể cung cấp một
accessPoint, đại diện cho một URL đơn giản hoặc bất kỳ dữ liệu thích hợp
khác, chẳng hạn như một số điện thoại với một đường dây trợ giúp hoặc một
hostingRedirector.
Người ta thường sử dụng
hostingRedirector khi ràng buộc
cho một dịch vụ thay đổi. Ví dụ, nếu tờ
*Daily Moon* đã thiết lập dịch vụ các
đoạn quảng cáo được phân loại của nó và cho phép cả hai tờ báo gửi các đoạn quảng cáo
lên bằng cách sử dụng cuộc gọi
createNewAdd(), thì tờ báo
này sẽ cần hoặc là đảm bảo rằng các dịch vụ không bao giờ thay đổi hoặc cung cấp một
cách để cho các ứng dụng khách biết dịch vụ đã thay đổi. Đó là nơi mà
hostingRedirector được dùng. Trong trường hợp đó, Francis
(hoặc trên thực tế là Gene) sẽ tạo ra một
bindingTemplate
mới, biểu thị cho các thông tin mới và nhập
bindingKey của
bindingTemplate đó vào trong thuộc tính
bindingKey của phần tử
hostingRedirector.
Việc xác định các dịch vụ làm gì thậm chí có thể còn khó khăn hơn. Lý do của việc này có hai phần. Trước tiên, vì chúng ta không nhất thiết phải nói về một dịch vụ SOAP, bạn không thể chỉ cần cung cấp một tệp WSDL. Thứ hai, vì điều này được hiểu là một quá trình tự động, nên bạn cần cung cấp thông tin này theo một cách như vậy là hoàn toàn rõ ràng.
Kết quả là
bindingTemplate bao gồm một phần tử
tModelInstanceDetails, trong đó có một hoặc nhiều phần tử
tModelInstanceDetail. Mỗi một trong số các phần tử đó
bao gồm một hoặc nhiều phần tử
tModelInstanceInfo, trỏ đến
một
tModel cụ thể. Một lần nữa, chúng ta sẽ nói về
tModels ngay sau đây. Tuy nhiên, điều quan trọng cần hiểu là
phần tử
tModelInstanceInfo có thể chứa một phần tử
instanceDetails, mà bản thân phần tử instanceDetails lại chứa
một
overviewDoc, bao gồm
overviewURL, một URL cho một tài liệu thực sự xác định dịch vụ đó. (Đúng,
đó là nơi bạn xác định tệp WSDL).
TModels (bao gồm cả
tModel của
tModels)
Bây giờ hãy nói về
tModels.
tModels thực sự nhằm vào hai mục đích. Đầu tiên, như chúng
ta đã thấy một chút trong cuộc thảo luận về
publisherAssertions, là một phần của "bộ chỉ thị vùng tên". Nói cách khác,
một
tModel có thể cung cấp cách để phân biệt giữa các kiểu
thông tin có thể dẫn đến nhầm lẫn. Một ví dụ như mã số thuế hoặc giá trị khác dễ nhầm
với các số. Ví dụ, một
keyedReference có những điều sau
dường như không cung cấp tất cả các thông tin, vì hai mã nhận dạng thuế này thuộc về
các nước khác nhau. Trong cả hai nước, chúng được gọi là mã số thuế, nhưng theo lập
trình, chúng ta phải có một cách để phân biệt giữa chúng, như trong
[Liệt kê 6](#list6).
##### Liệt kê 6. Các mã số thuế của các nước khác nhau
<keyedReference tModelKey="" keyName="taxid" keyValue="11111111" /> <keyedReference tModelKey="" keyName="taxid" keyValue="22222222" />
Đó là nơi một
tModel được dùng. Chúng ta có thể tạo một
mô hình chính cho "mã số thuế của Hoa Kỳ" và một mô hình cho "mã số thuế của Mexico"
và v.v. Một khi chúng ta tạo các mô hình đó, chúng ta có thể sử dụng các khóa
tModel của các mô hình để đánh giá kỹ hơn nữa các
keyedReferences. Xem
[Liệt kê 7](#list7).
##### Liệt kê 7.
tModels và
keyedReferences
<tModel tModelKey="902CDE50-D53A-11DA-B055-A74C17FA61A7"> <name>United States codes</name> </tModel> <tModel tModelKey="062377D0-D5F5-11DA-8170-8ACF057FECAD"> <name>Mexico codes</name> </tModel> <keyedReference tModelKey="902CDE50-D53A-11DA-B055-A74C17FA61A7" keyName="taxid" keyValue="11111111" /> <keyedReference tModelKey="062377D0-D5F5-11DA-8170-8ACF057FECAD" keyName="taxid" keyValue="22222222" />
Cách sử dụng khác của
tModel là như một trình nhận dạng
đặc tả. Ví dụ, Francis biết rằng Gene là sẽ tạo các mục cho
ClassifiedService mà hai nhân viên này đã làm trong tháng trước. Dịch vụ
này biểu thị một giao diện cụ thể và như vậy, người ta có thể nhận biết dịch vụ này
bằng cách sử dụng một
tModel.
tModel này có thể trông giống như thứ được hiển thị trong
[Liệt kê 8](#list8).
##### Liệt kê 8.
tModel
<tModel tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A"operator="optional" authorizedName="optional"> <name>Classified Service Interface</name> <description></description> <overviewDoc> <description></description> <overviewURL> http://www.daily-moon.com/ClassifiedService-interface.wsdl </overviewURL> <overviewDoc> <identifierBag> ... </identifierBag> <categoryBag> ... </categoryBag> </tModel>
Cũng như với mọi đối tượng khác mà chúng ta đã xem xét
tModel có một khóa duy nhất, đó là thông tin cần thiết duy nhất. Tuy
nhiên, trong trường hợp này, chúng ta cũng muốn xác định
overviewURL, có nghĩa là URL cho tệp WSDL của giao diện. (Chúng ta sẽ tạo
nó trong phần tiếp theo).
Một lần nữa, người ta có thể nhận biết
tModels bằng cách
sử dụng một
identifierBag và được phân loại bằng cách sử
dụng một
categoryBag. Hãy xem chúng hoạt động như thế
nào.
identifierBag
Vì UDDI nhằm vào tính linh hoạt, nên không có cách cụ thể nào để nhận biết một
businessEntity. UDDI không yêu cầu nhận biết một doanh nghiệp theo số D-U-N-S của nó
hoặc theo mã số thuế của nó hoặc bằng bất kỳ phương pháp nhận biết cụ thể khác. Thay
vào đó, UDDI cung cấp một thùng chứa (container) trong đó bạn có thể đặt bao nhiều
trình nhận dạng tùy ý khi cần thiết, như bạn thấy trong
[Liệt kê
9](#list9).
##### Liệt kê 9.
indentifierBag
Mỗi
keyedReference được bạn thêm vào trong một
identifierBag biểu thị cơ hội khác cho những người dùng tìm
thấy đối tượng đang nói đến trong một tìm kiếm.
categoryBag
categoryBag hoạt động như
identifierBag, trong đó nó có chứa một hoặc nhiều
keyedReferences. Xem
[Liệt kê 10](#list10).
##### Liệt kê 10.
categoryBag
<categoryBag> <keyedReferencetModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag>
Trong trường hợp này, Francis đã tạo một
categoryBag cho
thấy rằng tờ Daily Moon là một văn phòng chi nhánh của tờ báo. Bây giờ hãy xem cách
sử dụng tất cả các đối tượng này.
## Ánh xạ WSDL tới UDDI
Trước khi Gene có thể viết bất kỳ mã nào để gửi tất cả các thông tin này tới đăng ký UDDI, Gene phải thực hiện một kết nối quan trọng giữa các dịch vụ hiện tại của họ và UDDI. Gene phải làm thích nghi các dịch vụ hiện tại này với khái niệm của UDDI về các dịch vụ, các giao diện và các khuôn mẫu ràng buộc.
### Các dịch vụ so với các giao diện
Cách nhìn của UDDI về một dịch vụ, như bạn có thể nhớ lại, bao gồm ba phần: giao
diện, được xác định bằng cách sử dụng
tModels;
businessService; và
bindingTemplate, liên kết hai trong số chúng lại với nhau. Vì vậy, bước
đầu tiên của Gene là tìm hiểu tệp WSDL định nghĩa dịch vụ SOAP có thể khớp trong cấu
trúc này như thế nào.
Bước đầu tiên của Gene là phân chia WSDL. May mắn thay, điều này khá đơn giản. Giao
diện này bao gồm tất cả các mảnh của tệp WSDL trừ ra việc thực hiện thực tế của nó.
Xem
[Liệt kê 11](#list11).
##### Liệt kê 11. Giao diện WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.apache.org/axis2" xmlns:axis2="http://ws.apache.org/axis2" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace="http://ws.apache.org/axis2"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://org.apache.axis2/xsd" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:element type="ns1:ClassifiedAd" name="ClassifiedAd" /> <xs:complexType name="ClassifiedAd"> <xs:sequence> <xs:element type="xs:int" name="id" /> <xs:element type="xs:string" name="content" /> <xs:element type="xs:string" name="endDate" /> <xs:element type="xs:string" name="startDate" /> </xs:sequence> </xs:complexType> ... </xs:schema> </wsdl:types> <wsdl:message name="createNewAdRequestMessage"> <wsdl:part name="part1" element="ns1:createNewAdRequest" /> </wsdl:message> <wsdl:message name="createNewAdResponseMessage"> <wsdl:part name="part1" element="ns1:createNewAdResponse" /> </wsdl:message> ... <wsdl:portType name="ClassifiedServicePortType"> <wsdl:operation name="finalizeIssue"> <wsdl:input message="tns:finalizeIssueRequestMessage" /> </wsdl:operation> <wsdl:operation name="createNewAd"> <wsdl:input message="tns:createNewAdRequestMessage" /> <wsdl:output message="tns:createNewAdResponseMessage" /> </wsdl:operation> ... </wsdl:portType> <wsdl:binding name="ClassifiedServiceBinding" type="tns:ClassifiedServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <wsdl:operation name="createNewAd"> <soap:operation soapAction="createNewAd" style="document" /> <wsdl:input> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace="http://ws.apache.org/axis2" /> </wsdl:output> </wsdl:operation> ... </wsdl:binding> </wsdl:definitions>
Giao diện này bao gồm các định nghĩa kiểu (lược đồ XML), các thông báo bất kỳ
portType ngay cả
binding (ràng
buộc), bởi vì ràng buộc không đặc trưng cho việc thực hiện cụ thể.
Việc thực hiện bao gồm phần tử dịch vụ thực tế. Xem
[Liệt kê
12](#list12).
##### Liệt kê 12. Việc thực hiện dịch vụ WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns= "http://www.daily-moon.com/ClassifiedService-interface" xmlns:axis2="http://ws.apache.org/axis2" xmlns:ns1="http://org.apache.axis2/xsd" targetNamespace= "http://www.daily-moon.com/ClassifiedService-interface"> <wsdl:import namespace="http://ws.apache.org/axis2" location= "http://www.nicholaschase.com/ClassifiedService-interface.wsdl" /> <wsdl:service name="ClassifiedService"> <wsdl:port name="ClassifiedServicePort" binding="axis2:ClassifiedServiceBinding"> <soap:address location= "http://www.daily-moon.com:8080/axis2/services/ClassifiedService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Lưu ý rằng tệp thực hiện nhập khẩu tệp giao diện. Nói cách khác, tệp này là định nghĩa đầy đủ của dịch vụ.
Bây giờ hãy xem tệp đó tương ứng với các đối tượng UDDI của chúng ta như thế nào.
### Ánh xạ giao diện tới một
tModel
Đầu tiên Gene đã phải ánh xạ giao diện tới một
tModel
thích hợp. Xem
[Liệt kê 13](#list13).
##### Liệt kê 13.
tModel
<tModel tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <name>http://www.daily-moon.com/ClassifiedService- interface</name> <description>Interface for the Daily Moon Classified Department web application</description> <overviewDoc> <description>WSDL interface document</description> <overviewURL> http://www.daily-moon.com/ClassifiedService-interface.wsdl </overviewURL> <overviewDoc> <categoryBag> <keyedReference tModelKey="C1ACF26D-9672-4404-9D70-39B756E62AB4" keyName="uddi-org:types" keyValue="wsdlSpec" /> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </tModel>
Bắt đầu từ phía dưới cùng, lưu ý
categoryBag. Gene đã thêm
vào hai
keyReferences. Tham chiếu đầu tiên quy định rằng
trên thực tế chúng ta đang xử lý một tệp WSDL. Người ta đã xác định trước
tModelKey cụ thể đó để biểu thị vùng tên
uddi-org:types. Tất cả các tệp WSDL phải được xác định theo cách này. Tham
chiếu thứ hai được liên kết với vùng tên
ntis-gov:naics:1997 do đó, thật dễ dàng cho những người dùng của Gene tìm
định nghĩa này trong số tất cả các tệp WSDL biểu thị các dịch vụ phải làm với các tờ
báo. Tiếp tục lên, chúng ta thấy
overviewDoc. Ngoài mô tả
tùy chọn, nó xác định URL thực tế mà chúng ta có thể tìm thấy tệp WSDL ở đó.
Cuối cùng, tên của
tModel phải khớp với vùng tên đích của
tệp WSDL.
### Ánh xạ việc thực hiện với một khuôn mẫu ràng buộc
Tiếp theo Gene phải ánh xạ chính việc thực hiện này tới một
bindingTemplate. Xem
[Liệt kê 14](#list14).
##### Liệt kê 14.
bindingTemplate
<bindingTemplate serviceKey="" bindingKey=""> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> <tModelInstanceDetails> <tModelInstanceDetail> <tModelInstanceInfo tModelKey="66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <instanceDetails> <description>The canonical implementation of the Daily Moon's classified service.</description> <overviewDoc> <overviewURL> http://www.daily-moon.com/ClassifiedService-impl.wsdl </overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetail> </tModelInstanceDetails> </bindingTemplate>
Ở đây chúng ta thấy rằng Gene tạo một
bindingTemplate mới,
thiết lập
accessPoint như URL cho dịch vụ thực tế
modelInstanceDetails chủ yếu liên kết giao diện
tModel (qua
tModelKey) với tài
liệu thực hiện (được quy định trong
overviewDoc). Bây giờ
Gene chỉ phải tham chiếu nó từ dịch vụ.
### Tham chiếu
bindingTemplate từ
businessService và
businessEntity
Bước cuối cùng là đặt
bindingTemplate tất cả lại với nhau
và tham chiếu
businessService và
businessService từ
businessEntity. Xem
[Liệt kê 15](#list15).
##### Liệt kê 15.
businessEntity đầy đủ
<businessEntity businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>The Daily Moon</name> <name lang="fr-ca">La Lune Quotidienne</name> <contacts> <contact> <personName>Pat Mooney</personName> <email>patm@daily-moon.com</email> </contact> </contacts> <businessServices> <businessService serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7"> <name>ClassifiedService</name> <bindingTemplates> <bindingTemplate bindingKey="904BD800-D53A-11DA-B055-850A1DA99D79"> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> <tModelInstanceDetails> <tModelInstanceDetail> <tModelInstanceInfo tModelKey= "66999A50-D5F4-11DA-9A50-FA44D6AD622A"> <instanceDetails> <description>The canonical implementation of the Daily Moon's classified service.</description> <overviewDoc> <overviewURL> http://www.daily-moon.com/ClassifiedService-impl.wsdl </overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetail> </tModelInstanceDetails> </bindingTemplate> </bindingTemplates> <categoryBag> <keyedReference tModelKey="C1ACF26D-9672-4404-9D70-39B756E62AB4" keyName="uddi-org:types" keyValue="wsdlSpec" /> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </businessService> </businessServices> <identifierBag> <keyedReference tModelKey="4064C064-6D14-4F35-8953-9652106476A9" keyName="DUNS Number" keyValue="55555555" /> <keyedReference tModelKey="" keyName="US Tax ID" keyValue="111111111" /> </identifierBag> <categoryBag> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </businessEntity>
Nói cách khác, dịch vụ đã hoàn tất: bây giờ Gene có một
businessEntity bao gồm một dịch vụ
## Tìm và sử dụng thông tin
Bây giờ tất cả các thông tin có trong dịch vụ, ít nhất về mặt lý thuyết, Gene cần phải xem xét quá trình để tìm kiếm thông tin một lần nữa.
### Các việc tìm kiếm của UDDI hoạt động như thế nào: tìm kiếm một doanh nghiệp
Việc tìm kiếm trong UDDI gồm hai bước. Đầu tiên, bạn tìm khóa của đối tượng mà bạn
muốn và sau đó bạn lấy thông tin về đối tượng đó. Cuối cùng, để cho Gene tìm một
doanh nghiệp, Gene cần tạo một yêu cầu
find_business, như
trong
[Liệt kê 16](#list16).
##### Liệt kê 16. Tìm một doanh nghiệp theo thể loại
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <categoryBag> <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </find_business>
Yêu cầu này sẽ tìm tất cả các doanh nghiệp khớp với các thể loại được tham chiếu
trong
categoryBag. Các việc tìm kiếm về giá trị
categoryBag được xử lý như một việc tìm kiếm ""VÀ" (AND). Nói
cách khác, mục bất kỳ trùng khớp ít nhất là một trong các thể loại phải khớp. Bạn
cũng có thể xác định một tìm kiếm
identifierBag theo cách
này. Tuy nhiên, Gene không thực sự quan tâm đến tìm kiếm theo thể loại. Vào lúc này,
Gene chỉ muốn xem có hay không có doanh nghiệp trong đăng ký, do đó để thay thế Gene
thích tìm kiếm theo tên hơn, như trong
[Liệt kê 17](#list17).
##### Liệt kê 17. Tìm một doanh nghiệp theo tên
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <name>daily</name> </find_business>
Lưu ý rằng một tìm kiếm theo tên được xử lý như thể tên mà bạn đang tìm kiếm tiếp sau
là một ký tự đại diện. Nói cách khác, việc tìm kiếm ở đây là giống như thực hiện một
tìm kiếm với
"daily*", do đó cả
*Daily Moon* và
*Daily Star* và bất kỳ doanh nghiệp khác nào bắt đầu với từ "daily" sẽ hiển
thị. Những tìm kiếm này cũng phân biệt chữ hoa, chữ thường.
### Việc tìm kiếm tìm thấy gì
find_business yêu cầu trả về một
businessList. Xem
[Liệt kê 18](#list18).
##### Liệt kê 18. Một tìm kiếm trả về các doanh nghiệp
<businessList generic="2.0" operator="uddi.sourceOperator" truncated="true" xmlns="urn:uddi-org:api_v2"> <businessInfos> <businessInfo businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691" > <name>The Daily Moon</name> <serviceInfos> <serviceInfo serviceKey= "064B4170-D5F5-11DA-8170-A74C17FA61A7"> <name>ClassifiedService</name> </serviceInfo> </serviceInfos> </businessInfo> <businessInfo> ... </businessInfo> </businessInfos> </businessList>
businessList bao gồm một phần tử
businessInfo cho mỗi
businessEntity thỏa mãn
tìm kiếm đó. Mỗi một trong số các phần tử
serviceInfo đó
có một
businessKey cho
businessEntity thực tế.
businessList cũng bao
gồm một phiên bản viết tắt của các thông tin sẽ được liệt kê trong
businessEntity, để bạn có thể có được một ý tưởng về liệu đây
có phải là một doanh nghiệp mà bạn đang tìm kiếm không.
Một khi bạn có
businessKey, thích hợp, bạn cần phải có
thêm thông tin về
businessEntity này.
### Một khi bạn có khóa
Để có thêm thông tin về một
businessEntity cụ thể dựa trên
businessKey, bạn cần phải thực hiện một yêu cầu
get_businessDetail. Xem
[Liệt kê 19](#list19).
##### Liệt kê 19. Nhận thông tin về các doanh nghiệp
<get_businessDetail generic="2.0" xmlns="urn:uddi-org:api_v2" > <businessKey>1A3DB880-D5F4-11DA-B880-F94D3591C691 </businessKey> </get_businessDetail>
Bạn có thể liệt kê càng nhiều
businessKeys trong một yêu
cầu
get_businessDetail như bạn muốn. Mỗi một businessKeys
sẽ có phần tử
businessDetail riêng của mình trong các kết
quả. Xem
[Liệt kê 20](#list20).
##### Liệt kê 20. Các chi tiết về doanh nghiệp được trả về
<businessDetail generic="2.0" operator="uddi.sourceOperator" truncated="false" xmlns="urn:uddi-org:api_v2"> <businessEntity businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>The Daily Moon</name> <name lang="fr-ca">La Lune Quotidienne</name> <contacts> ... <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="optional" keyValue="511110" /> </categoryBag> </businessEntity> </businessDetail>
Mỗi phần tử
businessDetail gồm toàn bộ
businessEntity của doanh nghiệp có liên quan.
### Thay đổi cách tìm kiếm hoạt động
Trong lúc tìm kiếm này hoạt động, có những lúc bạn muốn thay đổi hành vi của tìm kiếm
đó. Ví dụ, có lẽ bạn muốn tìm kiếm một sự trùng khớp chính xác hơn là một sự trùng
khớp của ký tự đại diện hoặc bạn muốn tìm kiếm theo chữ hoa hay chữ thường. Bạn có
thể thay đổi hành vi của việc tìm kiếm bằng cách sử dụng
findQualifiers. Xem
[Liệt kê 21](#list21).
##### Liệt kê 21. Sử dụng
findQualifiers
<find_business generic="2.0" xmlns="urn:uddi-org:api_v2" > <findQualifiers> <findQualifier>sortByNameAsc</findQualifier> <findQualifiers> <name>daily</name> </find_business>
Trong trường hợp này, việc tìm kiếm sẽ tiến hành như bình thường, nhưng kết quả sẽ
được trả về được sắp xếp theo tên. Bạn có thể thêm nhiều phần tử
findQualifier như bạn muốn. Trong số các phần tử có sẵn để sử dụng là
exactNameMatch,
caseSensitiveMatch,
sortByNameDesc, sortByDateAsc và
sortByDateDesc,
hay
LikeKeys (báo cho đăng ký biết để xử lý các khóa trong
một
categoryBag hoặc
identifierBag như là một điều kiện "HOẶC" (OR) nếu chúng chia sẻ cùng một
tModelKey) và
combineCategoryBags (xử lý tất cả các
categoryBags của một
businessEntity, liệu chúng
có thuộc về
businessEntity,
businessService hoặc
bindingTemplate, không,
nếu như chúng thuộc về
businessService đó).
### Tìm một kiểu dịch vụ
Gene cũng muốn đảm bảo rằng những người dùng có thể tìm bất kỳ dịch vụ nào dựa trên
một giao diện cụ thể. Ví dụ, truy vấn này sẽ định vị
bindingTemplates mà bạn sử dụng giao diện
ClassifiedService. Xem
[Liệt kê 22](#list22).
##### Liệt kê 22. Tìm một
bindingTemplate
<find_binding generic="2.0" xmlns="urn:uddi-org:api_v2" > <tModelBag> <tModelKey>66999A50-D5F4-11DA-9A50-FA44D6AD622A</tModelKey> </tModelBag> </find_binding>
Truy vấn này trả về một
serviceList. Xem
[Liệt kê 23](#list23).
##### Liệt kê 23. Các dịch vụ được trả về
<serviceList generic="2.0" operator="uddi.sourceOperator" xmlns="urn:uddi-org:api_v2"> <serviceInfos> <serviceInfo serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7" businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>ClassifiedService</name> </serviceInfo> </serviceInfos> </serviceList>
Như trong trường hợp với
find_business, sau đó bạn đã phải
quay trở lại đó và yêu cầu thông tin về
businessEntity,
rồi bạn sẽ xác định thông tin yêu cầu trên các máy chủ dựa trên
serviceKey. Xem
[Liệt kê 24](#list24).
##### Liệt kê 24. Nhận các chi tiết dịch vụ
<get_serviceDetail generic="2.0" xmlns="urn:uddi-org:api_v2" > <serviceKey>064B4170-D5F5-11DA-8170-A74C17FA61A7 </serviceKey> </get_serviceDetail>
Truy vấn này trả về một
serviceDetail cho mỗi
serviceKey cụ thể. Xem
[Liệt kê 25](#list25).
##### Liệt kê 25. Các chi tiết dịch vụ được trả về
<serviceDetail generic="2.0" operator="uddi.sourceOperator" xmlns="urn:uddi-org:api_v2"> <businessService serviceKey="064B4170-D5F5-11DA-8170-A74C17FA61A7" businessKey="1A3DB880-D5F4-11DA-B880-F94D3591C691"> <name>ClassifiedService</name> <bindingTemplates> <bindingTemplate bindingKey="904BD800-D53A-11DA-B055-850A1DA99D79"> <accessPoint> http://www.daily-moon.com:8080/axis2/services/ClassifiedService </accessPoint> ... <keyedReference tModelKey="C0B9FE13-179F-413D-8A5B-5004DB8E5BB2" keyName="ntis-gov:naics:1997" keyValue="511110" /> </categoryBag> </businessService> <businessService> ... </businessService> </serviceDetail>
Bây giờ Gene biết những gì mình muốn làm, anh ta sẵn sàng bắt đầu viết mã.
## Làm việc với UDDI theo chương trình
Công việc cuối cùng của Gene là thiết lập một nhóm các ứng dụng bằng chứng-cho-nội dung để hiển thị cho các nhóm khác có thể xây dựng các ứng dụng dựa trên đăng ký UDDI như thế nào.
### Thiết lập
Bước đầu tiên trong khi làm việc với một đăng ký UDDI là phần mềm đăng ký của chính UDDI, nhưng Gene ngạc nhiên thích thú phát hiện ra rằng do tờ báo đang sử dụng Apache Geronimo làm máy chủ ứng dụng Web của mình, nên bước đó dễ dàng được Apache Geronimo quan tâm đến; Geronimo đi kèm với Apache jUDDI được cài đặt sẵn.
Điều đó đã được thực hiện, Gene phải quyết định cách anh ta thực sự sẽ truy cập vào đăng ký. Ở đây, Gene có hai sự lựa chọn. Sự lựa chọn đầu tiên là thực hiện đăng ký trực tiếp, sử dụng một UDDI dựa trên các API như một UDDI có trong jUDDI hoặc UDDI4J. Sự lựa chọn thứ hai là sử dụng một việc thực hiện JAXR (Java API cho Các đăng ký XML - Java API for XML Registries). JAXR được dự định để truy cập vào bất kỳ đăng ký nào, với sự hỗ trợ UDDI và ebXML là mục tiêu chính của nó.
Gene quyết định đi thẳng vào mã nguồn và tải UDDI4J. Nói cách khác, UDDI4J phụ thuộc vào một số các thư viện được phân phối cùng với Apache Axis, do đó Gene cũng tải Apache Axis. (Lưu ý rằng mặc dù các phần trước của dự án này đã sử dụng Axis2, UDDI4J phụ thuộc vào các thư viện phân phối cùng với Axis 1).
Việc thiết lập khá đơn giản, đòi hỏi Gene chỉ cần đảm bảo rằng tất cả các tệp UDDI4J
và tệp Axis *. jar cần thiết có trên đường dẫn lớp (classpath) này. Xem
[Liệt kê 26](#list26).
##### Liệt kê 26. Việc thiết lập tập hợp
CLASSPATH=.; <UDDI4J_HOME>\lib\uddi4j.jar; <AXIS_HOME>\lib\axis.jar; <AXIS_HOME>\lib\saaj.jar; <AXIS_HOME>\lib\jaxrpc.jar; <AXIS_HOME>\lib\log4j-1.2.8.jar; <AXIS_HOME>\lib\commons-logging-1.0.4.jar; <AXIS_HOME>\lib\commons-discovery-0.2.jar;
Cuối cùng, Gene cần một tên người dùng và mật khẩu để kết nối đến đăng ký. Về mặt
này, mỗi đăng ký là khác nhau, vì vậy chúng ta sẽ không đi vào chi tiết. Việc cài đặt
mặc định của UDDI trong Apache Geronimo sử dụng một tên người dùng và mật khẩu là
"juddi".
### Kết nối tới đăng ký
Bước đầu tiên trong bất kỳ ứng dụng nào là kết nối tới đăng ký. Xem
[Liệt kê 27](#list27).
##### Liệt kê 27. Kết nối tới đăng ký
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; public class CreateNewBusiness { public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); } catch(Exception e ) { e.printStackTrace(); } } }
Bắt đầu từ đầu, Gene thiết lập các giá trị khác nhau mà Gene sẽ cần trong suốt ứng
dụng. Cụ thể, Gene đặt tên lớp cho
TransportFactory.
UDDI4J có thể sử dụng số lượng bất kỳ của các lớp thích hợp, chẳng hạn như một lớp đi
kèm với Apache Axis, như bạn thấy ở đây, một lớp đi kèm với gói Apache SOAP cũ hoặc
bất cứ thứ gì tương tự.
Cuối cùng, Gene thiết lập các giá trị
inquiryURL và
publishURL cho đăng ký đó -- các giá trị này thường sẽ khác
nhau, một phần vì việc xuất bản luôn được thực hiện bằng cách sử dụng SSL -- và yêu
cầu một thẻ (token) ủy quyền.
Thẻ này rất quan trọng vì nó là cách mỗi yêu cầu biểu thị rằng nó đã được xác thực với máy chủ. Bởi vì mỗi đăng ký xử lý những thứ khác nhau, nên để duy trì việc gửi tên người dùng và mật khẩu với mỗi yêu cầu là không thực tế (hoặc an toàn).
Khi chạy ứng dụng này, Gene thấy một kết quả như sau:
Security
authToken:authToken:505A7DE0-D897-11DA-A5BF-ADFF17B378CF
### Tạo một thực thể kinh doanh
Tiếp theo Gene muốn tạo một thực thể kinh doanh. Xem
[Liệt kê
28](#list28).
##### Liệt kê 28. Tạo
businessEntity
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory;
import org.uddi4j.datatype.business.BusinessEntity; import org.uddi4j.response.BusinessDetail; import org.uddi4j.datatype.business.Contact; import org.uddi4j.datatype.business.Contacts; import org.uddi4j.util.KeyedReference; import org.uddi4j.util.IdentifierBag; import org.uddi4j.util.CategoryBag; import org.uddi4j.datatype.tmodel.TModel; import java.util.Vector;public class CreateNewBusiness { public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String businessName = "The Daily Moon"; String alt_businessName = "Daily Moon"; String contact_personName = "Pat Moonie"; String contact_phone = "212-555-1212"; String identifier_homepage = "http://www.daily-moon.com"; String category_NAICS = "511110";String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); Vector entities = new Vector(); BusinessEntity newBusiness = new BusinessEntity("", businessName); Contact newContact = new Contact(contact_personName); Vector contactsVector = new Vector(); contactsVector.addElement(newContact); Contacts contacts = new Contacts(); contacts.setContactVector(contactsVector); newBusiness.setContacts(contacts); KeyedReference taxid = new KeyedReference(TModel.HOMEPAGE_TMODEL_KEY, identifier_homepage); IdentifierBag idBag = new IdentifierBag(); i dBag.add(taxid); newBusiness.setIdentifierBag(idBag); KeyedReference category = new KeyedReference(TModel.NAICS_TMODEL_KEY, category_NAICS); CategoryBag catBag = new CategoryBag(); catBag.add(category); entities.addElement(newBusiness); BusinessDetail bd = proxy.save_business(token.getAuthInfoString(), entities); Vector businessEntities = bd.getBusinessEntityVector(); BusinessEntity returnedBusinessEntity = (BusinessEntity) (businessEntities.elementAt(0)); System.out.println("The new businessKey:" + returnedBusinessEntity.getBusinessKey());} catch(Exception e ) { e.printStackTrace(); } } }
Quá trình kết hợp một
businessEntity với nhau về cơ bản
bao gồm các phần tử xây dựng giống như chúng đang ở trong XML, với dạng "số nhiều"
(như
"contacts" (các liên hệ),
"tModelInfos" và v.v) được xử lý như các vectơ.
Trong trường hợp này, Gene xây dựng vector liên hệ
identifierBag và
categoryBag và thêm các vector
liên hệ này vào đối tượng
BusinessEntity. Đối tượng tự nó
được thêm vào một Vector, tức là các phương thức
save_business() này, cùng với thẻ uỷ quyền.
Kết quả là một đối tượng
BusinessDetail có chứa một hoặc
nhiều đối tượng
BusinessEntity khi các đối tượng này có
trong cơ sở dữ liệu. Trong trường hợp này, Gene gửi
BusinessEntity đi mà không cần một giá trị cho
businessKey, để cho đăng ký biết tạo một đối tượng mới và do đó tạo một
khóa mới. Bằng cách lấy
BusinessEntity đầu tiên từ vectơ,
sau đó Gene có thể có được một
businessKey mới.
Khi chạy ứng dụng này, Gene nhận được kết quả được hiển thị trong
[Liệt kê 29](#list29):
##### Liệt kê 29. Nhận được một businessKey mới
Security authToken:authToken:1D05DB90-D899-11DA-A5BF-D3513DE466CA The new businessKey:1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7
### Tạo một giao diện dịch vụ
tModel
Với doanh nghiệp tại chỗ, tiếp theo Gene bắt đầu thêm giao diện dịch vụ. Xem
[Liệt kê 30](#list30).
##### Liệt kê 30. Tạo một
tModel
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector;
import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.response.TModelDetail; import org.uddi4j.datatype.OverviewURL; import org.uddi4j.datatype.OverviewDoc; import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference;public class CreateNewInterface{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); Vector tModels = new Vector(); TModel tModel = new TModel("", "http://www.daily-moon.com/classifieds-interface"); tModel.setDefaultDescriptionString( "Interface for the Daily Moon Classified "+ "Department web application"); OverviewDoc overviewDoc = new OverviewDoc(); overviewDoc.setDefaultDescriptionString( "WSDL interface document"); OverviewURL overviewURL = new OverviewURL( "http://www.nicholaschase.com/ClassifiedsService-interface.wsdl"); overviewDoc.setOverviewURL(overviewURL); tModel.setOverviewDoc(overviewDoc); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); tModel.setCategoryBag(catBag); tModels.add(tModel); TModelDetail tModelDetail = proxy.save_tModel(token.getAuthInfoString(), tModels); Vector tModelVector = tModelDetail.getTModelVector(); TModel tModelReturned = (TModel)(tModelVector.elementAt(0)); System.out.println("TModel Saved: " + tModelReturned.getNameString()); System.out.println("TModel Key : " + tModelReturned.getTModelKey());} catch(Exception e ) { e.printStackTrace(); } } }
Như trước, Gene bắt đầu tạo mô hình phần tử XML trong mã Java. Gene bắt đầu bằng cách
tạo
TModel, lại không có khóa để biểu thị rằng anh ta tạo
một đối tượng mới và thiết lập sự mô tả. Sau đó Gene tạo
OverviewDoc, bao gồm sự mô tả và
OverviewURL.
Tiếp theo, Gene tạo
KeyedReferences cho
CategoryBag. Lưu ý rằng Gene sẽ tham chiếu
tModels, cụ thể, vì thế Gene cung cấp
tModelKey cho mỗi một trong số chúng; giá trị này là tùy chọn. Cuối cùng,
Gene lưu
TModel, một lần nữa lấy ra đối tượng từ giá trị
được trả về.
Việc chạy ứng dụng cung cấp cho Gene kết quả được hiển thị trong
[Liệt kê 31](#list31):
##### Liệt kê 31. Nhận được một khóa tModel mới
Security authToken:authToken:3312DF20-D8A1-11DA-A5BF-D754085751C9 TModel Saved: http://www.daily-moon.com/classifieds-interface TModel Key : uuid:332F67D0-D8A1-11DA-A5BF-DF15F533BFA1
### Tạo một dịch vụ
Tạo chính dịch vụ đó theo cùng thủ tục cơ bản. Xem
[Liệt kê
32](#list32).
##### Liệt kê 32. Tạo dịch vụ
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector;
import org.uddi4j.datatype.business.BusinessEntity; import org.uddi4j.datatype.service.BusinessService; import org.uddi4j.datatype.binding.BindingTemplate; import org.uddi4j.datatype.binding.BindingTemplates; import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference; import org.uddi4j.datatype.binding.AccessPoint; import org.uddi4j.datatype.binding.TModelInstanceDetails; import org.uddi4j.datatype.binding.TModelInstanceInfo; import org.uddi4j.datatype.binding.InstanceDetails; import org.uddi4j.datatype.OverviewDoc; import org.uddi4j.datatype.OverviewURL; import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.response.ServiceDetail;public class CreateNewService{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String businessKey = "1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7";String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); BusinessService businessService = new BusinessService(""); businessService.setDefaultNameString( "ClassifiedService",null); businessService.setBusinessKey(businessKey); BindingTemplate bindingTemplate = new BindingTemplate(); AccessPoint accessPoint = new AccessPoint( "http://www.daily-moon.com:8080/axis2/services/ClassifiedService","http"); bindingTemplate.setAccessPoint(accessPoint); TModelInstanceDetails tModelDetails = new TModelInstanceDetails(); TModelInstanceInfo tModelInstanceInfo = new TModelInstanceInfo( "332F67D0-D8A1-11DA-A5BF-DF15F533BFA1"); InstanceDetails instanceDetails = new InstanceDetails(); OverviewDoc overviewDoc = new OverviewDoc(); OverviewURL overviewURL = new OverviewURL( "http://www.nicholaschase.com/ClassifiedService-impl.wsdl"); overviewDoc.setOverviewURL(overviewURL); instanceDetails.setOverviewDoc(overviewDoc); tModelInstanceInfo.setInstanceDetails(instanceDetails); tModelDetails.add(tModelInstanceInfo); bindingTemplate.setTModelInstanceDetails(tModelDetails); BindingTemplates bindingTemplates = new BindingTemplates(); bindingTemplates.add(bindingTemplate); businessService.setBindingTemplates(bindingTemplates); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); businessService.setCategoryBag(catBag); Vector services = new Vector(); services.addElement(businessService); ServiceDetail serviceDetail = proxy.save_service( token.getAuthInfoString(), services); Vector businessServices = serviceDetail.getBusinessServiceVector(); BusinessService businessServiceReturned = (BusinessService) (businessServices.elementAt(0)); String serviceKey = businessServiceReturned.getServiceKey(); System.out.println("The Name: "+ businessServiceReturned.getDefaultNameString()); System.out.println("The ServiceKey: "+ serviceKey);} catch(Exception e ) { e.printStackTrace(); } } }
Đến nay Gene đã thấy mô hình quen thuộc; tạo các đối tượng như chúng tồn tại trong
tài liệu XML. Hãy tạo
BusinessService và thêm
businessKey. Tạo
BindingTemplate,
bảo đảm tham chiếu
tModelKey được tạo khi Gene đã tạo giao
diện
tModel và URL cho tệp WSDL thực tế. Tạo
categoryBag thêm nó vào và lưu dịch vụ. Lấy ra dịch vụ và tên
và khóa của nó. Việc chạy ứng dụng đã cho Gene kết quả đầu ra được hiển thị trong
[Liệt kê 33](#list33).
##### Liệt kê 33. Lấy ra khóa tên dịch vụ
Security authToken:authToken:E4203390-D8A5-11DA-A5BF-8F6C6FEDFEBD The Name: ClassifiedService The ServiceKey: E43F2D40-D8A5-11DA-A5BF-880A3C83523B
### Tìm một doanh nghiệp
Tiếp theo Gene xem xét hướng đưa các tìm kiếm đó vào hoạt động. Gene bắt đầu một tìm
kiếm doanh nghiệp, cố gắng đảm bảo rằng tờ báo này đã được nhập vào đăng ký và người
ta chưa sao chép nó. Xem
[Liệt kê 34](#list34).
##### Liệt kê 34. Tìm một doanh nghiệp
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector;
import org.uddi4j.datatype.Name; import org.uddi4j.response.BusinessInfo; import org.uddi4j.response.BusinessList; import org.uddi4j.util.FindQualifier; import org.uddi4j.util.FindQualifiers;public class FindBusiness{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); String businessToFind = "The Daily Moon"; Vector names = new Vector(); names.add(new Name(businessToFind)); FindQualifiers findQualifiers = new FindQualifiers(); Vector qualifier = new Vector(); qualifier.add(new FindQualifier("exactNameMatch")); findQualifiers.setFindQualifierVector(qualifier); BusinessList businessList = proxy.find_business(names, null, null, null,null,findQualifiers,5); Vector businessInfoVector = businessList.getBusinessInfos().getBusinessInfoVector(); for( int i = 0; i < businessInfoVector.size(); i++ ){ BusinessInfo businessInfo = (BusinessInfo)businessInfoVector.elementAt(i); System.out.println(businessInfo.getDefaultNameString() + ": " + businessInfo.getBusinessKey());} } catch(Exception e ) { e.printStackTrace(); } } }
Gene sẽ tìm kiếm một giá trị tên cụ thể, vì đó là kiểu tìm kiếm mà Gene xây dựng.
Gene tạo một
Vector của các đối tượng tên chỉ có một mục
và tạo một
FindQualifier để xác định rằng Gene chỉ tìm
kiếm một sự so khớp chính xác. Cuối cùng, Gene cung cấp yêu cầu cho phương thức
find_business(), để nhận các tên làm các tham số, bất kỳ
discoveryURLs nào, một
IdentifierBag,
CategoryBag,
TModelBag,
FindQualifiers bất kỳ và số lượng
tối đa của các kết quả để trả về.
Kết quả là một
BusinessList, thông qua đó Gene lặp đi lặp
lại để xem tất cả các giá trị của nó trong trường hợp thông tin được sao chép. Đối
với mỗi giá trị, Gene in tên và
businessKey như bạn thấy
trong
[Liệt kê 35](#list35).
##### Liệt kê 35. Tên doanh nghiệp và businessKey
Security authToken:authToken:DBEAE280-D8A8-11DA-A5BF-A6D55D3D237D The Daily Moon: 1D359E20-D899-11DA-A5BF-F9EAF6D4E3F7 The Daily Moon: 1A3DB880-D5F4-11DA-B880-F94D3591C691
Trong trường hợp này, Gene có thể thấy rằng thông tin được sao chép, vì vậy Gene có
thể cung cấp
businessKey bổ sung cho phương thức
delete_business() của đối tượng
UDDIProxy .
### Tìm một dịch vụ
Tiếp theo, Gene muốn đảm bảo có thể tìm thấy
ClassifiedService theo thể loại của nó. Xem
[Liệt kê
36](#list36).
##### Liệt kê 36. Tìm một kiểu dịch vụ
import org.uddi4j.client.UDDIProxy; import org.uddi4j.response.AuthToken; import org.uddi4j.transport.TransportFactory; import java.util.Vector;
import org.uddi4j.util.CategoryBag; import org.uddi4j.util.KeyedReference; import org.uddi4j.datatype.tmodel.TModel; import org.uddi4j.datatype.binding.BindingTemplate; import org.uddi4j.datatype.binding.TModelInstanceInfo; import org.uddi4j.datatype.binding.TModelInstanceDetails; import org.uddi4j.datatype.binding.AccessPoint; import org.uddi4j.datatype.binding.InstanceDetails; import org.uddi4j.datatype.service.BusinessService; import org.uddi4j.response.ServiceDetail; import org.uddi4j.response.ServiceInfo; import org.uddi4j.response.ServiceList;public class FindTypeOfService{ public static void main (String args[]){ String inquiryURL = "http://localhost:8080/juddi/inquiry"; String publishURL = "http://localhost:8080/juddi/publish"; String userId = "juddi"; String credential = "juddi"; String transportClass = "org.uddi4j.transport.ApacheAxisTransport"; System.setProperty(TransportFactory.PROPERTY_NAME, transportClass); UDDIProxy proxy = new UDDIProxy(); try { proxy.setInquiryURL(inquiryURL); proxy.setPublishURL(publishURL); AuthToken token = proxy.get_authToken(userId, credential); System.out.println("Security authToken:" + token.getAuthInfoString()); KeyedReference wsdlNotation = new KeyedReference(TModel.TYPES_TMODEL_KEY, "wsdlSpec", "C1ACF26D-9672-4404-9D70-39B756E62AB4"); KeyedReference typeNotation = new KeyedReference("ntis-gov:naics:1997", "511110", "C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"); CategoryBag catBag = new CategoryBag(); catBag.add(wsdlNotation); catBag.add(typeNotation); ServiceList serviceList = proxy.find_service(null, null, catBag,null,null,5); Vector serviceInfoVector = serviceList.getServiceInfos().getServiceInfoVector(); for( int i = 0; i < serviceInfoVector.size(); i++ ){ ServiceInfo serviceInfo = (ServiceInfo)serviceInfoVector.elementAt(i); System.out.println("Service name: " + serviceInfo.getDefaultNameString()); System.out.println("Service key: " + serviceInfo.getServiceKey()); ServiceDetail serviceDetail = proxy.get_serviceDetail (serviceInfo.getServiceKey()); BusinessService thisService = (BusinessService)serviceDetail .getBusinessServiceVector().elementAt(0); if (thisService.getBindingTemplates().size() > 0){ BindingTemplate thisBinding = (BindingTemplate)thisService .getBindingTemplates().get(0); TModelInstanceDetails tModelDetails = thisBinding.getTModelInstanceDetails(); TModelInstanceInfo tModelInfo = tModelDetails.get(0); InstanceDetails instanceDetails = tModelInfo.getInstanceDetails(); String wsdlDocument = instanceDetails.getOverviewDoc() .getOverviewURLString(); System.out.println("Document located at " + wsdlDocument); } }} catch(Exception e ) { e.printStackTrace(); } } }
Bước đầu tiên của Gene là tạo một
CategoryBag cho phép
Gene tìm kiếm tất cả WSDL đã xác định các dịch vụ phải làm với các tờ báo. Kết quả
của việc tìm kiếm đó là một
ServiceList, thông qua đó Gene
lặp đi lặp lại để có thêm thông tin. Một đối tượng
ServiceInfo biểu thị từng dịch vụ trong kết quả và Gene kết nối qua mỗi
một trong số các dịch vụ, hiển thị tên và serviceKey của các dịch vụ
serviceKey.
Tuy nhiên, nếu Gene muốn biết thêm chi tiết, chẳng hạn như URL cho các tệp WSDL, Gene
phải sử dụng
serviceKey để yêu cầu
ServiceDetail cho dịch vụ đó.
ServiceDetail
không có hay có nhiều
BindingTemplates được liên kết với
nó và nếu Gene tìm thấy một BindingTemplate, Gene thực hiện cách của mình xuống dưới
thông qua đối tượng
TModelInstanceDetails tới đối tượng
InstanceDetails, trong đó bao gồm
OverviewDoc và vì thế gồm cả
OverviewURL. Kết
quả hiển thị không chỉ tên và
serviceKey của dịch vụ kết
quả, mà còn là URL mà người dùng có thể tìm thêm thông tin ở đó. Xem
[Liệt kê 37](#list37).
##### Liệt kê 37. Các kết quả cuối cùng
Security authToken:authToken:59FE37C0-D8AF-11DA-A5BF-A79333DB92F9 Service name: ClassifiedService Service key: E43F2D40-D8A5-11DA-A5BF-880A3C83523B Document located at http://www.nicholaschase.com/ClassifiedService-impl.wsdl
## Tóm tắt
Một môi trường phân tán đòi hỏi một kho lưu trữ tập trung để những người dùng và các nhà phát triển biết cái gì có sẵn và nơi tìm nó và các dịch vụ Web không là ngoại lệ. Hướng dẫn này đã giải thích việc sử dụng UDDI, cung cấp một đăng ký thông tin về các doanh nghiệp và dịch vụ có sẵn.
Trong hướng dẫn này, bạn đã học:
- UDDI là gì và tại sao nó lại quan trọng.
- Làm thế nào để cấu trúc dữ liệu UDDI.
- Làm thế nào để phân biệt giữa các giao diện và các việc hiện thực SOAP.
- Làm thế nào để tìm dữ liệu trong một đăng ký UDDI.
- Làm thế nào để tương tác với một đăng ký UDDI bằng cách sử dụng Java.
Các phần tiếp theo của loạt bài này sẽ bàn về các nhu cầu an ninh ngày càng tăng, xem xét Các ứng dụng Web-an ninh (WS-Security) và Các ứng dụng Web-Chính sách (WS-Policy).
## Tải về
|Mô tả||Tên||Kích thước|
|Source code|
## Tài nguyên
### Học tập
- Đọc
[các hướng dẫn khác trong loạt bài này](http://www.ibm.com/developerworks/vn/views/webservices/libraryview.jsp ?search_by=Hiểu+biết+về+Đặc+tả+các+dịch+vụ+Web).
- Truy cập
[trang UDDI](http://www.uddi.org).
- Bạn có thể tìm
[các đặc tả cho tất cả ba phiên bản](http://www.oasis-open.org/committees/uddi-spec/doc/tcspecs.htm), bao gồm các tài liệu lược đồ XML.
- Xem những thay đổi trong phiên bản UDDI 3.0 trong
[Bay đi xa hơn với UDDI V3](http://www.ibm.com/developerworks/webservices/library/ws-uddiv3/?S_TACT=105AGY75)của Tom Bellwood.
- Đối với một loạt ba phần về các phương thức khác nhau sử dụng WSDL với các đăng ký UDDI, xem loạt bài của developerWorks "Hiểu biết về WSDL trong một đăng ký UDDI:"
- Đọc loạt bài trên developerWorks "Vai trò của các nút
UDDI riêng biệt trong các dịch vụ web:"
[Phần 1: Sáu loại UDDI](http://www.ibm.com/developerworks/webservices/library/ws-rpu1.html?S_TACT=105AGY75)(05.2001) [Phần 2: Các nút riêng và các nút toán tử](http://www.ibm.com/developerworks/webservices/library/ws-rpu2.html?S_TACT=105AGY75)(05.2001)
- Đọc loạt bài năm phần "Một cách tiếp cận mới tới UDDI
và WSDL:"
[Phần 1: Giới thiệu về Chú giải kỹ thuật UDDI WSDL của OASIS mới](http://www.ibm.com/developerworks/webservices/library/ws-udmod1/?S_TACT=105AGY75)(08.2003) [Phần 2: Các câu hỏi được Chú giải kỹ thuật UDDI WSDL của OASIS mới hỗ trợ](http://www.ibm.com/developerworks/webservices/library/ws-udmod2.html?S_TACT=105AGY75)(09.2003) [Phần 3: Một ví dụ về Chú giải kỹ thuật UDDI WSDL của OASIS mới đang hoạt động](http://www.ibm.com/developerworks/webservices/library/ws-udmod3/?S_TACT=105AGY75)(10.2003) [Phần 4: Xuất bản từ Java bằng cách sử dụng Chú giải kỹ thuật UDDI WSDL của OASIS mới](http://www.ibm.com/developerworks/webservices/library/ws-udmod4/?S_TACT=105AGY75)(03.2004) [Phần 5: Truy vấn từ một ứng dụng Java bằng cách sử dụng Chú giải kỹ thuật UDDI WSDL của OASIS mới](http://www.ibm.com/developerworks/webservices/library/ws-udmod4/?S_TACT=105AGY75)(11.2004)
- Tìm hiểu thêm về UDDI4J:
[UDDI4J: Kết hợp với các dịch vụ Web](http://www.ibm.com/developerworks/webservices/library/ws-uddi4j.html?S_TACT=105AGY75).
- Xem:
[Programming with UDDI4J version 2](http://www.ibm.com/developerworks/webservices/library/ws-uddi4j2.html?S_TACT=105AGY75)(developerWorks, 07. 2002) với một bài viết thảo luận về tính lặp lại tiếp theo của API khách của UDDI, UDDI4J v2,
### Lấy sản phẩm và công nghệ
- Tải
[Apache Geronimo](http://geronimo.apache.org/downloads.html).
- Để tạo đăng ký UDDI riêng của
bạn, tải
[Apache jUDDI](http://ws.apache.org/juddi/releases.html).
- Tải
[UDDI4J](http://sourceforge.net/projects/uddi4j/).
- Tải
[Apache Axis 1.3](http://www.apache.org/dyn/closer.cgi/ws/axis/1_3).
- Tải
[Java 1.4.2](http://java.sun.com/j2se/1.4.2/download.html). Geronimo sẽ không chạy đúng với Java 1.5. [UDDI4Py](http://www.alphaworks.ibm.com/tech/uddi4py)là gói Python cho phép gửi các yêu cầu đến và xử lý các đáp ứng từ các API phiên bản 2 của UDDI.
### Thảo luận
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US