須將 Axis 相關 JAR 加入 Client 端 Classpath(勿放入 JRE ext 目錄):
axis.jar、jaxrpc.jar、commons-logging-1.0.4.jar、commons-discovery-0.2.jar、saaj.jar、wsdl4j-1.5.1.jaractivation.jar、mail.jar(若服務端使用)建議在 ~/.profile 或 IDE 專案設定中配置 CLASSPATH。
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import java.net.URL;
public class BookSearcherClient {
private static final String ENDPOINT = "https://localhost:8080/axis/BookSearcher.jws";
private Service service;
private Call call;
private URL endpointUrl;
public Object[] search(String keyword) throws Exception {
if (service == null) service = new Service();
if (call == null) call = (Call) service.createCall();
if (endpointUrl == null) endpointUrl = new URL(ENDPOINT);
call.setTargetEndpointAddress(endpointUrl);
call.setOperationName(new QName("https://soapinterop.org/", "search"));
// 呼叫遠端方法,參數以 Object[] 傳遞
Object[] results = (Object[]) call.invoke(new Object[] { keyword });
return results;
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println("Usage: java BookSearcherClient [keyword]");
return;
}
BookSearcherClient client = new BookSearcherClient();
Object[] books = client.search(args[0]);
System.out.println("Returned books for keyword '" + args[0] + "':");
for (Object b : books) System.out.println(" " + b);
}
}
Service 為 Factory 產生 Call。setTargetEndpointAddress() 指定 .jws URL。QName 表達 SOAP 操作,命名空間固定 https://soapinterop.org/,本地名為方法名 search。Object[],同步阻塞呼叫,回傳結果亦為 Object[](SOAP 不保留泛型資訊)。$ java BookSearcherClient design
Returned books for keyword 'design':
Emotional Design
Indexed
結果與伺服器端直接測試一致,證明 RPC 呼叫成功。
wsimport 由 WSDL 產生 Stub,避免手寫 QName 與 invoke 細節。