jaxws-rt 修復已知 Bug)。<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC) // RPC 風格,文檔風格用 DOCUMENT
public interface MyFirstWebService {
@WebMethod
String sayHi(@WebParam(name = "name") String name);
}
@WebService(endpointInterface = "com.rambo.cwe.jws.inter.MyFirstWebService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class MyFirstWebServiceImpl implements MyFirstWebService {
@Override
public String sayHi(String name) {
return "Hi, " + name + "!";
}
}
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>MyFirstWebService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyFirstWebService</servlet-name>
<url-pattern>/services/sayHi</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="https://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="myFirstWebService"
implementation="com.rambo.cwe.jws.impl.MyFirstWebServiceImpl"
url-pattern="/services/sayHi"/>
</endpoints>
啟動 Tomcat,訪問 https://localhost:8080/ctx/services/sayHi?wsdl 應顯示 WSDL 文檔。
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 自動發布所有 @WebService Bean -->
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="https://localhost:8089/services/"/>
</bean>
<!-- 服務實現 Bean -->
<bean id="myFirstWebServiceImpl" class="com.rambo.cwe.jws.impl.MyFirstWebServiceImpl"/>
或使用注解 @Component + 掃描。啟動 Spring 容器即自動發布。
wsimport -keep -p com.client.proxy https://localhost:8080/ctx/services/sayHi?wsdl
MyFirstWebServiceImplService service = new MyFirstWebServiceImplService();
MyFirstWebService port = service.getMyFirstWebServiceImplPort();
System.out.println(port.sayHi("Orson"));
URL wsdlUrl = new URL("https://localhost:8080/ctx/services/sayHi?wsdl");
QName serviceName = new QName("https://impl.jws.cwe.rambo.com/", "MyFirstWebServiceImplService");
QName portName = new QName("https://impl.jws.cwe.rambo.com/", "MyFirstWebServiceImplPort");
Service service = Service.create(wsdlUrl, serviceName);
MyFirstWebService port = service.getPort(portName, MyFirstWebService.class);
System.out.println(port.sayHi("Orson"));
Dispatch dispatch = service.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
DOMSource request = ... // 構建 SOAP Body
Source response = dispatch.invoke(request);
| 問題 | 解決 |
|---|---|
| WSDL 訪問 404 | 檢查 url-pattern、sun-jaxws.xml、endpointInterface 三者一致 |
| 中文亂碼 | 確保 JDK/容器編碼 UTF-8,SOAP 消息頭 Content-Type: text/xml; charset=utf-8 |
| 附件傳輸 (MTOM) | 接口加 @MTOM,客戶端 ((BindingProvider)port).getRequestContext().put("mtom-enabled", true) |
| 超時設置 | ((BindingProvider)port).getRequestContext().put("com.sun.xml.ws.connect.timeout", 5000); |
| 安全認證 | 配置 WS-Security (WSS4J) 或 HTTP Basic Auth 於 BindingProvider |
JAX-WS 以「內置、標準、輕量」三大優勢,成為 Java 內部 SOAP/Web Service 集成的首選。掌握「純 Servlet 發布」「Spring 整合」「三種客戶端調用」三大場景,配合 wsimport 代碼生成,即可應對 90% 以上的企業級集成需求。下次跨語言、跨平台對接時,拋出一個 WSDL 地址,世界就安靜了。