想要將現有的 Java 類別發布為 Web Service?使用 Apache Axis 只需三個關鍵步驟即可完成:
完成部署後,客戶端只需透過 wsdl2java 工具根據 WSDL 生成 Stub 程式碼,即可輕鬆呼叫遠端服務。這種分層架構讓前台頁面、控制邏輯、資料傳輸與處理徹底解耦,特別適合將 CICS 等後台系統逐層封裝現代化。
webapps 目錄下的 axis 資料夾複製到 TOMCAT_HOME/webapps/ 下。https://localhost:8080/axis 驗證安裝是否成功(預設會顯示 Axis 歡迎頁與可用服務列表)。Axis 提供三種 Web Service 部署與呼叫方式,適用於不同場景:
| 模式 | 特點 | 適用場景 |
|---|---|---|
| Dynamic Invocation Interface (DII) | 客戶端動態構建呼叫,無需預先生成 Stub | 快速原型、動態發現服務 |
| Stubs 方式 | 預先生成強型別 Stub,編碼體驗佳 | 正式專案、團隊協作開發 |
| Dynamic Proxy 方式 | 基於介面的動態代理,程式碼更簡潔 | 介面導向設計、解耦合需求高 |
public class HelloClient {
public String getName(String name) {
return "hello " + name;
}
}
將編譯後的類別檔複製到 AXIS_HOME 目錄下,並重新命名為 HelloClient.jws。Axis 會自動偵測並發布。
瀏覽器訪問 https://localhost:8080/axis/HelloClient.jws?wsdl,即可看到 Axis 自動生成的 WSDL 文檔。
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
public class TestHelloClient {
public static void main(String[] args) {
try {
String endpoint = "https://localhost:8080/axis/HelloClient.jws";
Service service = new Service();
Call call = (Call) service.createCall();
call.setOperationName(new QName("https://localhost:8080/axis/HelloClient.jws", "getName"));
call.setTargetEndpointAddress(new java.net.URL(endpoint));
String ret = (String) call.invoke(new Object[] {"張三"});
System.out.println("return value is " + ret);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public interface HelloClientInterface extends java.rmi.Remote {
public String getName(String name) throws java.rmi.RemoteException;
}
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import java.net.URL;
import javax.xml.namespace.QName;
public class TestHelloClient {
public static void main(String[] args) {
try {
String wsdlUrl = "https://localhost:8080/axis/HelloClient.jws?wsdl";
String namespaceUri = "https://localhost:8080/axis/HelloClient.jws";
String serviceName = "HelloClientService";
String portName = "HelloClient";
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new URL(wsdlUrl), new QName(namespaceUri, serviceName));
HelloClientInterface proxy = (HelloClientInterface) service.getPort(new QName(namespaceUri, portName), HelloClientInterface.class);
System.out.println("return value is " + proxy.getName("John"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
package server;
public class SayHello {
public String getName(String name) {
return "hello " + name;
}
}
import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import java.util.Date;
public class LogHandler extends BasicHandler {
public void invoke(MessageContext msgContext) throws AxisFault {
try {
Handler serviceHandler = msgContext.getService();
Integer numAccesses = (Integer) serviceHandler.getOption("accesses");
if (numAccesses == null) numAccesses = new Integer(0);
numAccesses = new Integer(numAccesses.intValue() + 1);
Date date = new Date();
String result = date + ": service " + msgContext.getTargetService() + " accessed " + numAccesses + " time(s).";
serviceHandler.setOption("accesses", numAccesses);
System.out.println(result);
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
}
}
<deployment xmlns="https://xml.apache.org/axis/wsdd/"
xmlns:java="https://xml.apache.org/axis/wsdd/providers/java">
<handler name="print" type="java:LogHandler"/>
<service name="sayhello" provider="java:RPC">
<requestFlow>
<handler type="print"/>
</requestFlow>
<parameter name="className" value="server.SayHello"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
server 與 LogHandler 類別複製到 AXIS_HOME/WEB-INF/classes。java org.apache.axis.client.AdminClient deploy.wsddjava org.apache.axis.wsdl.WSDL2Java -p client https://localhost:8080/axis/services/SayHello.jws?wsdljava org.apache.axis.wsdl.Java2WSDL -o SayHello.wsdl -l https://localhost:8080/axis/services/SayHello -n sayhello server.SayHellojava org.apache.axis.wsdl.WSDL2Java SayHello.wsdl -p client
生成的 Stub 檔案包含:SayHello.java、SayHelloService.java、SayHelloServiceLocator.java、SayHelloSoapBindingStub.java。
public class SayHelloClient {
public static void main(String[] args) {
try {
SayHelloService service = new client.SayHelloServiceLocator();
client.SayHello_PortType client = service.getSayHello();
String retValue = client.getName("張三");
System.out.println(retValue);
} catch (Exception e) {
System.err.println("Execution failed. Exception: " + e);
}
}
}
生產環境通常直接編輯 server-config.wsdd 以集中管理所有服務與全域設定(如密碼、附件處理、傳輸協定等)。以下為關鍵片段:
<deployment xmlns="https://xml.apache.org/axis/wsdd/"
xmlns:java="https://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="sendXMLDeclaration" value="true"/>
</globalConfiguration>
<handler name="print" type="java:stub.LogHandler"/>
<service name="sayhello" provider="java:RPC">
<requestFlow><handler type="print"/></requestFlow>
<parameter name="className" value="stub.server.SayHello"/>
<parameter name="allowedMethods" value="*"/>
</service>
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
</transport>
</deployment>