環境說明
Java JDK 1.8、Spring boot 2.1.6、Apache CXF 3.1.6
POM依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.6</version>
</dependency>
</dependencies>
服務端
webService接口
使用@WebService聲明式注解聲明這是一個webService接口,並設置:
- name:服務名稱
- targetNamespace:命名空間,通常是接口的包名倒序
注解@WebMethod是聲明接口方法,可以通過operationName為接口方法設置別名,默認是方法名。
此外他還有一個參數exclude,為true時則忽略該方法作為webService接口方法,默認為false。
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(name = "TestService",
targetNamespace = "http://server.dandelion.com")
public interface TestService {
@WebMethod(operationName="getData")
@WebResult(targetNamespace = "http://server.dandelion.com")
String execute(@WebParam(name = "action") String action, @WebParam(name = "msg") String msg);
}
創建了webService接口TestService,其中方法execute有兩個參數分別為action和msg,用注解@WebParam進行聲明。
接口實現
創建接口實現類TestServiceImpl實現TestService接口,其中endpointInterface為webService接口的路徑。
import javax.jws.WebService;
@WebService(serviceName = "TestService"
targetNamespace = "http://server.dandelion.com",
endpointInterface = "com.dandelion.server.TestService")
public class TestServiceImpl implements TestService{
@Override
public String execute(String action, String msg) {
System.out.println(String.format("action: %s", action));
System.out.println(String.format("msg: %s", msg));
return "<root><code>1</code><msg>同步成功</msg></root>";
}
}
注冊接口
創建webService的配置類WebServiceConfig,將接口服務注入容器並進行發布。
import com.dandelion.server.TestServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class WebServiceConfig {
@Bean
public ServletRegistrationBean<CXFServlet> disServlet() {
ServletRegistrationBean<CXFServlet> servletRegistrationBean = new ServletRegistrationBean<>();
servletRegistrationBean.setServlet(new CXFServlet());
servletRegistrationBean.addUrlMappings("/webService/*");
return servletRegistrationBean;
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint(SpringBus springBus) {
EndpointImpl endpoint = new EndpointImpl(springBus, new TestServiceImpl());
endpoint.publish("/testService");
return endpoint;
}
}
項目啟動效果:
配置完成后啟動項目,訪問http://localhost:服務端口/webService,如下圖所示說明創建webService服務成功。
WSDL文件:訪問http://localhost:服務端口/webService/testService?wsdl
SoapUI測試
客戶端
JAX動態調用WebService工具類
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class WsClientUtil {
/**
* 調用webservice服務
* @param wsdUrl 服務地址
* @param operationName 方法名稱
* @param params 參數
* @return 服務響應結果
*/
public static String callWebService(String wsdUrl, String operationName, Object... params){
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdUrl);
try {
Object[] objects = client.invoke(operationName, params);
return objects[0].toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
API測試
@RestController
@RequestMapping(value = "/client")
public class TestClientController {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
@RequestMapping(value = "test")
public String test(){
//在獲取連接之前 還原上下文
Thread.currentThread().setContextClassLoader(classLoader);
// 服務地址
String url = "http://localhost:9010/webService/testService?wsdl";
// 方法名稱
String methodName = "getData";
// 參數1
String action = "同步用戶信息";
// 參數2
String msg = "<user><id>10012334223</id><name>蒲公英不是夢</name><sex>1</sex></user>";
try {
// 發起請求
return WsClientUtil.callWebService(url, methodName, action, msg);
} catch (Exception e) {
return String.format("webService調用異常:%s", e.getMessage());
}
}
}
效果