Các dịch vụ Web Java JAXB và JAX-WS trong Axis2
Sử dụng các công nghệ tiêu chuẩn Java JAXB 2.x và JAX-WS 2.x cho các dịch vụ
Web Axis2
Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc.
Tóm tắt: Apache Axis2 hỗ trợ một loạt các công nghệ liên kết dữ liệu, bao gồm
tiêu chuẩn Java™ chính thức JAXB 2.x . Axis2 cũng hỗ trợ tiêu chuẩn Java cho
cấu hình dịch vụ Web, JAX-WS 2.x, như là một sự thay thế cho kỹ thuật cấu hình
tùy chỉnh riêng của nó. Dennis Sosnoski tiếp tục loạt bài Các dịch vụ Web Java
của mình bằng cách giải thích bạn có thể sử dụng mỗi tiêu chuẩn Java này với
Axis2 như thế nào và thảo luận về một số hạn chế về sự hỗ trợ hiện tại của Axis2
cho chúng.
Axis của Apache ban đầu đã dựa vào các tiêu chuẩn Java đầu tiên cho các dịch vụ
Web, JAX-RPC. Điều này hóa ra không phải là một cách tiếp cận tốt, vì JAX-RPC
đã hạn chế việc thiết kế nội bộ của mã Axis và đã góp phần gây ra cảvấn đề hiệu
năng lẫn sự thiếu linh hoạt. JAX-RPC cũng đặt một số giả định về hướng phát
triển các dịch vụ Web mà sau này hóa ra là sai.
axws.GetBookResponse") public BookInformation getBook( @WebParam(name = "isbn", targetNamespace = "") String isbn); @WebMethod(action = "urn:getBooksByType") @WebResult(name = "getBooksByTypeReturn", targetNamespace = "") @RequestWrapper(localName = "getBooksByType", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.GetBooksByType") @ResponseWrapper(localName = "getBooksByTypeResponse", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.GetBooksByTypeResponse") public List getBooksByType( @WebParam(name = "type", targetNamespace = "") String type); @WebMethod(action = "urn:getTypes") @WebResult(name = "getTypesReturn", targetNamespace = "") @RequestWrapper(localName = "getTypes", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.GetTypes") @ResponseWrapper(localName = "getTypesResponse", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.GetTypesResponse") public List getTypes(); @WebMethod(action = "urn:addBook") @WebResult(name = "addBookReturn", targetNamespace = "") @RequestWrapper(localName = "addBook", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.AddBook") @ResponseWrapper(localName = "addBookResponse", targetNamespace = "", className = "com.sosnoski.ws.library.jaxws.AddBookResponse") public boolean addBook( @WebParam(name = "type", targetNamespace = "") String type, @WebParam(name = "isbn", targetNamespace = "") String isbn, @WebParam(name = "author", targetNamespace = "") List author, @WebParam(name = "title", targetNamespace = "") String title) throws AddDuplicateFault ; } Công cụ WsImport nhận ra WSDL được cung cấp là khớp với quy ước "được bao bọc" và tự động tạo ra một giao diện dịch vụ không được bao bọc. Bạn có thể thấy tác dụng của điều này trong Liệt kê 5 theo cách các phương thức lấy các giá trị riêng lẻ làm các tham số đầu vào và trả về trực tiếp bất kỳ kiểu nào thích hợp, thay vì sử dụng một tầng các đối tượng bao bọc (mặc dù các đối tượng của trình bao bọc vẫn được tạo ra và được sử dụng sau hậu trường trong thời gian chạy JAX- WS). Mã được cung cấp một lần nữa đưa ra một triển khai thực hiện thực tế của cả dịch vụ lẫn máy khách thử nghiệm. Để thử nghiệm nó, bạn cần phải chỉnh sửa tệp build.properties được cung cấp để thiết lập đường dẫn cho cả bản cài đặt Axis2 của bạn lẫn bản cài đặt thực hiện tham khảo JAX-WS (xem Tài nguyên). Khi chỉnh sửa xong, hãy gõ ant trong một bàn điều khiển mở tới thư mục jaxws để chạy tạo mã JAX-WS từ WSDL, biên dịch mã được cung cấp và xây dựng một tệp JAR cho việc triển khai máy chủ. Để chạy máy khách thử nghiệm, hãy sao chép tệp JAR đã tạo ra tới thư mục WEB-INF/servicejars của bản cài đặt Axis2 của bạn và sau đó gõ ant run trong bàn điều khiển. Cách sử dụng JAX-WS phía máy khách Liệt kê 6 cho thấy toàn bộ mã máy khách thử nghiệm. Nếu bạn so sánh mã này với Liệt kê 2, bạn sẽ thấy sự khác biệt giữa một giao diện được bao bọc và không được bao bọc, với giao diện không được bao bọc thân thiện với lập trình viên. Liệt kê 6. Mã máy khách thử nghiệm JAX-WS public class WebServiceClient { public static void main(String[] args) throws Exception { // check for required command line parameters if (args.length < 3) { System.out.println("Usage:\n java " + "com.sosnoski.ws.library.jaxws.WebServiceClient host port path"); System.exit(1); } // create the client stub JaxwsLibrary service = new JaxwsLibrary(); Library stub = service.getLibrary(); // set the actual endpoint address String target = "http://" + args[0] + ":" + args[1] + args[2]; System.out.println("Connecting to " + target); BindingProvider provider = (BindingProvider)stub; provider.getRequestContext(). put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, target); // retrieve a book directly String isbn = "0061020052"; BookInformation book = stub.getBook(isbn); if (book == null) { System.out.println("No book found with ISBN '" + isbn + '\''); } else { System.out.println("Retrieved '" + book.getTitle() + '\''); } // retrieve the list of types defined List types = stub.getTypes(); System.out.println("Retrieved " + types.size() + " types:"); for (int i = 0; i < types.size(); i++) { TypeInformation type = types.get(i); System.out.println(" '" + type.getName() + "' with " + type.getCount() + " books"); } // add a new book String title = "The Dragon Never Sleeps"; isbn = "0445203498"; try { List authors = new ArrayList(); authors.add("Cook, Glen"); stub.addBook("scifi", isbn, authors, title); System.out.println("Added '" + title + '\''); title = "This Should Not Work"; stub.addBook("scifi", isbn, authors, title); System.out.println("Added duplicate book - should not happen!"); } catch (AddDuplicateFault e) { System.out.println("Failed adding '" + title + "' with ISBN '" + isbn + "' - matches existing title '" + e.getFaultInfo().getBook().getTitle() + '\''); } // get all books of a type List books = stub.getBooksByType("scifi"); System.out.println("Retrieved " + books.size() + " books of type 'scifi':"); for (int i = 0; i < books.size(); i++) { System.out.println(" '" + books.get(i).getTitle() + '\''); } } } Việc xử lý phía máy khách JAX-WS nói chung được trông chờ là có truy cập tới WSDL dịch vụ trong thời gian chạy và nó sử dụng WSDL để khởi tạo liên kết máy chủ. Nếu bạn biết WSDL cho dịch vụ đích sẽ luôn luôn có sẵn trực tiếp từ máy chủ trong thời gian chạy và máy chủ sẽ luôn ở cùng một địa chỉ, bạn có thể chỉ cần cung cấp URL của WSDL cho WsImport và bắt nó mã hóa cứng URL vào mã được tạo ra. Đối với hầu hết công việc quan trọng, tốt hơn là sử dụng một bản sao cục bộ của WSDL và sau đó ghi đè lên địa chỉ dịch vụ đích trong thời gian chạy nếu nó khác với địa chỉ có trong WSDL. Tệp xây dựng được cung cấp dùng cách tiếp cận này và một phần của mã trong Liệt kê 6 được hiển thị bằng in đậm giải thích cách bạn có thể thay đổi địa chỉ dịch vụ trong thời gian chạy mà không thay đổi WSDL. Cách sử dụng JAX-WS phía máy chủ Phiên bản JAX-WS của mã phía máy chủ được hiển thị trong Liệt kê 7. Chú thích @WebService trên lớp thực hiện (được in đậm) liên kết đoạn mã thực hiện với một giao diện dịch vụ Web cụ thể. Chú thích này trên lớp thực hiện cho phép bạn ghi đè các giá trị cài đặt từ chú thích tương ứng trong giao diện dịch vụ được tạo ra (Liệt kê 5). Trong trường hợp này, chú thích thiết lập tên dịch vụ và tên cổng và cũng đưa ra vị trí của định nghĩa dịch vụ WSDL (mà Axis2 chờ đợi hoặc là đường dẫn tương đối so với gốc là đường dẫn lớp, hoặc là một URL tuyệt đối). Liệt kê 7. Mã máy chủ JAX-WS @javax.jws.WebService(endpointInterface="com.sosnoski.ws.library.jaxws.Library", portName="library", targetNamespace="", wsdlLocation="com/sosnoski/ws/library/jaxws/library.wsdl", serviceName="JaxwsLibrary") public class JaxwsLibraryImpl implements Library { private final BookServer m_server; public JaxwsLibraryImpl() { m_server = new BookServer(); } public boolean addBook(String type, String isbn, List author, String title) throws AddDuplicateFault { BookInformation prior = m_server.getBook(isbn); if (prior == null) { BookInformation book = new BookInformation(); book.getAuthor().addAll(author); book.setIsbn(isbn); book.setTitle(title); book.setType(type); return m_server.addBook(book); } else { AddDuplicate ad = new AddDuplicate(); ad.setBook(prior); AddDuplicateFault e = new AddDuplicateFault("Book already present with matching ISBN", ad); throw e; } } public BookInformation getBook(String isbn) { return m_server.getBook(isbn); } public List getBooksByType(String type) { return m_server.getBooksByType(type); } public List getTypes() { return m_server.getTypes(); } } Phần còn lại của đoạn mã trong Liệt kê 7 chỉ là một phiên bản không được bao bọc của phiên bản (được bao bọc) được hiển thị trong ví dụ JAXB trong Liệt kê 3. Các vấn đề JAX-WS trong Axis2 Axis2 làm việc rất tốt ở các điểm cơ bản về xử lý JAX-WS, nhưng nó có một số hạn chế. Đáng kể nhất là thiếu sự hỗ trợ cho WS-Security hoặc các công nghệ mở rộng các dịch vụ Web khác khi bạn sử dụng JAX-WS trong Axis2 (mặc dù các máy chủ ứng dụng đã xây dựng xung quanh Axis2 có thể thực hiện cách cấu hình và sử dụng WS-Security riêng của chúng). Đây là một hạn chế nghiêm trọng cho các ứng dụng doanh nghiệp và không có bất kỳ các lợi thế bù trừ nào, ngoại trừ một cách tiếp cận cấu hình đơn giản hơn một chút, và đó có vẻ không phải là lý do để sử dụng JAX-WS trong Axis2 ở thời điểm hiện nay. Tiến lên từ Axis2 Trong bài viết này, bạn đã thấy những điều cơ bản của việc sử dụng các tiêu chuẩn Java JAXB 2.x và JAX-WS 2.x với Axis2. Sự hỗ trợ JAXB trong Axis2 có một số hạn chế, nhưng ít nhất với các lược đồ đơn giản không yêu cầu các tùy chỉnh nó cung cấp một thay thế có ích cho các cách tiếp cận liên kết dữ liệu khác mà Axis2 hỗ trợ. Sự hỗ trợ JAX-WS bị hạn chế nhiều hơn và hiện tại chỉ có ích với các dịch vụ đơn giản không đòi hỏi WS-Security hoặc bất kỳ chức năng giá trị gia tăng nào khác. Cho đến nay các bài viết trong loạt bài này đã tập trung vào khung công tác Axis2 của Apache. Trình bày về JAXB và JAX-WS đã tạo ra một điểm xuất phát tuyệt vời để xem xét một số các khung công tác các dịch vụ Web Java mã nguồn mở khác cũng hỗ trợ các tiêu chuẩn này. Bài viết tháng tới sẽ xem xét làm việc với khung công tác Các dịch vụ Web Metro được Sun phát triển kết hợp với việc thực hiện tham khảo JAXB và JAX-WS. Nó cũng sẽ đi sâu thêm vào cách sử dụng và các tính năng của JAX-WS. Mục lục JAXB trong Axis2 Sử dụng JAX-WS trong Axis2 Tiến lên từ Axis2
File đính kèm:
- Các dịch vụ Web Java JAXB và JAX-WS trong Axis2.pdf