建議使用 JDK 1.6.10+,較低版本存在已知 Bug。
package org.enson.chan;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface IMyService {
int add(int a, int b);
int max(int a, int b);
}
package org.enson.chan;
import javax.jws.WebService;
@WebService(endpointInterface = "org.enson.chan.IMyService")
public class MyServiceImpl implements IMyService {
@Override
public int add(int a, int b) {
System.out.println(a + "+" + b + "=" + (a + b));
return a + b;
}
@Override
public int max(int a, int b) {
int result = (a > b) ? a : b;
System.out.println("比較大小,取最大值: " + result);
return result;
}
}
package org.enson.chan;
import javax.xml.ws.Endpoint;
public class MyServer {
public static void main(String[] args) {
String address = "https://localhost:8090/ns";
Endpoint.publish(address, new MyServiceImpl());
System.out.println("服務已發布至: " + address + "?wsdl");
}
}
package org.enson.chan;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class TestClient {
public static void main(String[] args) throws Exception {
URL url = new URL("https://localhost:8090/ns?wsdl");
QName qname = new QName("https://chan.enson.org/", "MyServiceImplService");
Service service = Service.create(url, qname);
IMyService proxy = service.getPort(IMyService.class);
System.out.println("add(12,33) = " + proxy.add(12, 33));
System.out.println("max(10,20) = " + proxy.max(10, 20));
}
}
適用於無 WSDL、需動態構建 SOAP 消息、添加 Header 等場景。
// 1. 純 SOAP 調用
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage msg = factory.createMessage();
SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
QName op = new QName("https://java.zttc.edu.cn/webservice", "add", "ns");
SOAPBodyElement elem = body.addBodyElement(op);
elem.addChildElement("a").setValue("22");
elem.addChildElement("b").setValue("33");
// 2. Dispatch 動態調用
URL wsdl = new URL("https://localhost:8989/ms?wsdl");
QName svcName = new QName("https://service.soap.org/", "MyServiceImplService");
Service svc = Service.create(wsdl, svcName);
Dispatch<SOAPMessage> dispatch = svc.createDispatch(
new QName("https://service.soap.org/", "MyServiceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
SOAPMessage response = dispatch.invoke(msg);
// 3. PAYLOAD 模式 + JAXB 綁定
Dispatch<Source> dispatch = svc.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
JAXBContext ctx = JAXBContext.newInstance(User.class);
Marshaller m = ctx.createMarshaller();
m.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter sw = new StringWriter();
m.marshal(user, sw);
String payload = "<nn:addUser xmlns:nn=\"" + ns + "\">" + sw.toString() + "</nn:addUser>";
Source resp = dispatch.invoke(new StreamSource(new StringReader(payload)));
// 4. 添加 SOAP Header(如認證)
SOAPHeader header = envelope.getHeader();
if (header == null) header = envelope.addHeader();
header.addHeaderElement(new QName(ns, "authInfo", "nn")).setValue("aabbccdd");
// 5. 處理 SOAPFault
try {
dispatch.invoke(msg);
} catch (SOAPFaultException e) {
System.out.println("服務端異常: " + e.getMessage());
}
No operation was found@SOAPBinding(style=RPC)