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

