開發接口 一、服務端開發 1、引入依賴
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-web-servicesartifactId>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxwsartifactId>
<version>3.1.6version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-transports-httpartifactId>
<version>3.1.6version>
dependency>
2、創建接口
package com.webserver.myb.service;
import org.springframework.stereotype.Component;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @Author mengyb
* @description TODO
* @Date 2023/1/28 10:12
* @Version 1.0
*/
@WebService(name = "MybBlog", // 與接口中指定的name一致
targetNamespace = "http://blogService.service.myb.blog.com", // 與接口中的命名空間一致,一般是接口的包名倒
)
public interface BlogService {
@WebMethod
public String send(@WebParam(name = "username") String username);
@WebMethod
public String message(@WebParam(name = "message") String message);
}
3、實現 接口
package com.webserver.myb.service.imppl;
import com.webserver.myb.service.BlogService;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
/**
* @Author mengyb
* @description TODO
* @Date 2023/1/28 10:15
* @Version 1.0
*/
@Component
@WebService(name = "MybBlog", // 與接口中指定的name一致
targetNamespace = "http://blogService.service.myb.blog.com", // 與接口中的命名空間一致,一般是接口的包名倒
endpointInterface = "com.webserver.myb.service.BlogService"// 接口地址
)
public class BlogServiceImpl implements BlogService {
@Override
public String send(String username) {
if ("zhangsan".equals(username)) {
return "張三";
}
return "李四,王五";
}
@Override
public String message(String message) {
return "====Hello ====WebServer===" + message;
}
}
4、創建配置文件
package com.webserver.myb.config;
import com.webserver.myb.service.BlogService;
import com.webserver.myb.service.imppl.BlogServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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;
/**
* @Author mengyb
* @description TODO
* @Date 2023/1/28 10:17
* @Version 1.0
*/
@Configuration
public class CxfConfig {
@Autowired
private BlogService blogService;
@Bean
public ServletRegistrationBean disServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/webService/*");
return servletRegistrationBean;
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), blogService);
endpoint.publish("/ws/api");
return endpoint;
}
}
5、啟動項目
訪問url: :8080/?wsdl
訪問url: :8080//ws/api?wsdl
【注】以上可以看到接口的相關信息,表示接口發布成功。
二、開發客戶端 1、導入依賴
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxwsartifactId>
<version>3.0.1version>
dependency>
2、生成客戶端代碼 2.1、使用idea在命令窗口,在指定的目錄下使用命令:
(生成客戶端代碼方式不唯一,看個人喜好)
// wsimport命令是jdk提供的,作用是根據使用說明書生成客戶端代碼,wsimport只支持SOAP1.1客戶端的生成
wsimport -keep -extension http://localhost:8080/webService/ws/api?wsdl
常用參數
-d:默認參數,用于生成.class文件
-s:生成.java文件
-p:指定生成java文件的包名戰地3該文件沒有與之關聯的程序來執行該操作,不指定則為WSDL說明書中值得倒寫
如下圖所示
3、測試客戶端 3.1、第一種方法
public static void main(String[] args) throws MalformedURLException {
BlogServiceImplService service = new BlogServiceImplService();
MybBlog mybBlogPort = service.getMybBlogPort();
String message = mybBlogPort.message("你好啊,2023年");
System.out.println("當前接受到的信息為----" + message);
String lisi = mybBlogPort.send("lisi");
System.out.println(lisi);
}
3.2、第二種方法
封裝客戶端請求
package com.webserver.customer.utils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
/**
* @Author mengyb
* @description TODO
* @Date 2023/1/28 11:08
* @Version 1.0
*/
public class ClientUtil {
public static String callWebSV(String url, String methodName, String... params) throws Exception {
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(url);
Object[] objects;
// invoke("方法名",參數1,參數2,參數3....);
objects = client.invoke(methodName, params);
return objects[0].toString();
}
}
測試方法
public static void main(String[] args) {
System.out.println("======開始調用webservice接口=====");
String url = "http://localhost:8080/webService/ws/api?wsdl";
String methodName = "send";
String result="";
try {
result= ClientUtil.callWebSV(url, methodName, "lisi");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("結果集為---" + result);
}
三、說明 1、對接口的wsdl文檔解析
一個WSDL文檔通常包含8個重要的元素,即、types、、、、、、元素。這些元素嵌套在元素中,是WSDL文檔的根元素。
WSDL 服務進行交互的基本元素: Types(消息類型):數據類型定義的容器,它使用某種類型系統(如 XSD)。
(消息):通信數據的抽象類型化定義,它由一個或者多個 part 組成。 Part:消息參數
(端口類型):特定端口類型的具體協議和數據格式規范。,它由一個或者多個 組成。
(操作):對服務所支持的操作進行抽象描述,WSDL定義了四種操作:
1.單向(one-way):端點接受信息;
3.要求-響應(-):端點發送消息戰地3該文件沒有與之關聯的程序來執行該操作,然后接受相關消息;
4.通知([2] ):端點發送消息。
:特定端口類型的具體協議和數據格式規范。
Port:定義為綁定和網絡地址組合的單個端點。
:相關端口的集合,包括其關聯的接口、操作、消息等。
外層結構里面也可能有多層結構。
2、Types
types元素作為一個容器,用于定義xml模式內置類型中沒有描述的各種數據類型。當聲明消息部分的有效時,消息定義使用了types元素中定義的數據類型和元素。
例如上面的例子:
該部分定義了兩個元素,send和sendResponse
send:定義了一個復雜類型,用于操作的參數傳入。并指明了參數的數據類型。
sendResponse:定義了一個復雜類型,包含了一個簡單的字符串,用于描述操作的返回值,并指明返回結果數據類型。
3、
元素可以在當前的WSDL文檔中使用其他WSDL文檔中指定的命名空間中的元素。
通常用于模塊化WSDL文檔。
必須有屬性和屬性:
1.屬性:值必須與正導入的WSDL文檔中生命的相匹配。
2.屬性:必須執行一個實際的WSDL文檔,并且該文檔不能為空
4、
元素描述了Web服務使用消息的有效負載。元素可以描述輸出或者接受消息的有效負載。還可以描述SOAP文件頭和錯誤元素的內容。定義元素的方式取決于使用RPC樣式還是文檔樣式的消息傳遞。
在文本中的元素的定義,本文檔使用了采用文檔樣式的消息傳遞:
5、
元素定義了Web服務的抽象接口。該接口有點類似Java的接口,都是定義了一個抽象類型和方法,沒有定義實現。在WSDL中,元素是由和元素來實現的,這兩個元素用來說明Web服務實現使用的協議、編碼方案、以及地址。
6、
元素將映射到一組具體協議(SOAP和HTTP),消息傳遞樣式、編碼樣式。通常元素與協議轉悠的元素和在一起使用。
7、 和 port
元素包含一個或者多個port元素,其中每個port元素表示一個不同的Web服務。port元素將URL賦給一個特定的,甚至可以使兩個或者多個port元素將不同的URL賦值給相同的。
【注】未完持續更新。。。。。。