前言
最近有個(gè)單位內(nèi)網(wǎng)系統(tǒng)需要對(duì)接統(tǒng)一門戶悦昵,進(jìn)行單點(diǎn)登錄和待辦事項(xiàng)對(duì)接功能。一般上政府系統(tǒng)都會(huì)要求做統(tǒng)一登錄功能辛臊,這個(gè)沒啥問題疹味,反正業(yè)務(wù)系統(tǒng)都是做單點(diǎn)登錄的仅叫,改下
shiro
相關(guān)類就好了〔谵啵看了接入方案惑芭,做坑爹的是需要業(yè)務(wù)系統(tǒng)提供一個(gè)webService
服務(wù),供統(tǒng)一平臺(tái)調(diào)用继找。對(duì)于ws
服務(wù),是真的除了大學(xué)期間要去寫個(gè)調(diào)用天氣預(yù)報(bào)的作業(yè)后逃沿,就再也沒有接觸過了婴渡。查閱了SpringBoot
文檔后,發(fā)現(xiàn)確實(shí)有一章節(jié)是將webService
的凯亮,所以边臼,今天就來簡單介紹下Spring Web Service
的集成和使用吧。
一點(diǎn)知識(shí)
何為WebService
Web Service
技術(shù)假消,能使得運(yùn)行在不同機(jī)器上的不同應(yīng)用無須借助附加的柠并、專門的第三方軟件或硬件, 就可相互交換數(shù)據(jù)或集成富拗。依據(jù)Web Service
規(guī)范實(shí)施的應(yīng)用之間臼予,無論它們所使用的語言、平臺(tái)或內(nèi)部協(xié)議是什么啃沪,都可以相互交換數(shù)據(jù)粘拾。
簡單的說,WebService就是一種跨編程語言和跨操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù)创千。
WebServcie技術(shù)支持
以下內(nèi)容摘自百度百科:Web Service
Web Service
平臺(tái)需要一套協(xié)議來實(shí)現(xiàn)分布式應(yīng)用程序的創(chuàng)建缰雇。任何平臺(tái)都有它的數(shù)據(jù)表示方法和類型系統(tǒng)。要實(shí)現(xiàn)互操作性追驴,Web Service
平臺(tái)必須提供一套標(biāo)準(zhǔn)的類型系統(tǒng)械哟,用于溝通不同平臺(tái)、編程語言和組件模型中的不同類型系統(tǒng)殿雪。這些協(xié)議有:
XML和XSD
可擴(kuò)展的標(biāo)記語言是Web Service
平臺(tái)中表示數(shù)據(jù)的基本格式暇咆。除了易于建立和易于分析外,XML
主要的優(yōu)點(diǎn)在于它既與平臺(tái)無關(guān),又與廠商無關(guān)糯崎。XML
是由萬維網(wǎng)協(xié)會(huì)(W3C)創(chuàng)建几缭,W3C制定的XML SchemaXSD定義了一套標(biāo)準(zhǔn)的數(shù)據(jù)類型,并給出了一種語言來擴(kuò)展這套數(shù)據(jù)類型沃呢。
Web Service
平臺(tái)是用XSD
來作為數(shù)據(jù)類型系統(tǒng)的年栓。當(dāng)你用某種語言如VB. NET
或C#
來構(gòu)造一個(gè)Web Service時(shí),為了符合Web Service
標(biāo)準(zhǔn)薄霜,所有你使用的數(shù)據(jù)類型都必須被轉(zhuǎn)換為XSD
類型某抓。如想讓它使用在不同平臺(tái)和不同軟件的不同組織間傳遞,還需要用某種東西將它包裝起來惰瓜。這種東西就是一種協(xié)議否副,如 SOAP
。
XSD
全稱為XML Schemas Definition
,即:XML結(jié)構(gòu)定義崎坊。是描述xml的备禀,同時(shí)遵循xml規(guī)范。
SOAP
SOAP
即簡單對(duì)象訪問協(xié)議(Simple Object Access Protocol)奈揍,它是用于交換XML(標(biāo)準(zhǔn)通用標(biāo)記語言下的一個(gè)子集)編碼信息的輕量級(jí)協(xié)議曲尸。它有三個(gè)主要方面:XML-envelope為描述信息內(nèi)容和如何處理內(nèi)容定義了框架,將程序?qū)ο缶幋a成為XML對(duì)象的規(guī)則男翰,執(zhí)行遠(yuǎn)程過程調(diào)用(RPC)的約定另患。SOAP可以運(yùn)行在任何其他傳輸協(xié)議上。例如蛾绎,你可以使用 SMTP昆箕,即因特網(wǎng)電子郵件協(xié)議來傳遞SOAP消息,這可是很有誘惑力的租冠。在傳輸層之間的頭是不同的鹏倘,但XML有效負(fù)載保持相同。
Web Service 希望實(shí)現(xiàn)不同的系統(tǒng)之間能夠用“軟件-軟件對(duì)話”的方式相互調(diào)用顽爹,打破了軟件應(yīng)用第股、網(wǎng)站和各種設(shè)備之間的格格不入的狀態(tài),實(shí)現(xiàn)“基于Web無縫集成”的目標(biāo)话原。
WSDL
Web Service
描述語言WSDL
就是用機(jī)器能閱讀的方式提供的一個(gè)正式描述文檔而基于XML
的語言夕吻,用于描述Web Service及其函數(shù)、參數(shù)和返回值繁仁。因?yàn)槭腔赬ML的涉馅,所以WSDL既是機(jī)器可閱讀的,又是人可閱讀的黄虱。
UDDI
UDDI
的目的是為電子商務(wù)建立標(biāo)準(zhǔn)稚矿;UDDI
是一套基于Web的、分布式的、為Web Service
提供的晤揣、信息注冊(cè)中心的實(shí)現(xiàn)標(biāo)準(zhǔn)規(guī)范桥爽,同時(shí)也包含一組使企業(yè)能將自身提供的Web Service
注冊(cè),以使別的企業(yè)能夠發(fā)現(xiàn)的訪問協(xié)議的實(shí)現(xiàn)標(biāo)準(zhǔn)昧识。
何為Spring-Web-Services
Spring Web services
是Spring
推出的一款構(gòu)建webservice
服務(wù)的框架钠四。其主要側(cè)重點(diǎn)是創(chuàng)建文檔驅(qū)動(dòng)的Web服務(wù)。Spring Web Services
項(xiàng)目促進(jìn)了契約優(yōu)先的SOAP服務(wù)開發(fā)跪楞,提供了多種方式來創(chuàng)建靈活的Web服務(wù)缀去,這些服務(wù)可以通過多種方式處理XML負(fù)載〉榧溃可無縫地使用Spring依賴注入和配置等概念缕碎。
Spring-WS
項(xiàng)目由由以下幾個(gè)項(xiàng)目組成:
Spring-WS Core(
spring-ws-core.jar
) - 它是主要模塊,提供WebServiceMessage和SoapMessage等中央接口池户,服務(wù)器端框架咏雌,強(qiáng)大的消息分發(fā)功能和支持類來實(shí)現(xiàn)Web服務(wù)端點(diǎn)。 它還提供Web Service消費(fèi)者客戶端作為:WebServiceTemplate校焦。Spring-WS Support(
spring-ws-support.jar
) ? 該模塊為JMS处嫌,電子郵件等提供支持。Spring-WS Security(
spring-ws-security.jar
) - 該模塊負(fù)責(zé)提供與核心Web服務(wù)模塊集成的WS-Security實(shí)現(xiàn)斟湃。 使用這個(gè)模塊,可以添加主體令牌檐薯,簽名凝赛,加密和解密SOAP消息。該模塊允許使用現(xiàn)有的Spring Security實(shí)現(xiàn)進(jìn)行認(rèn)證和授權(quán)坛缕。Spring XML(
spring-xml.jar
) ? 該模塊為Spring Web Services提供XML支持類墓猎。 該模塊由Spring-WS框架內(nèi)部使用。Spring OXM - 該模塊提供了XML與對(duì)象映射的支持類赚楚。
之間的依賴關(guān)系毙沾,如下圖所示:
簡單來說,看了官網(wǎng)文檔后宠页,一切遵循契約優(yōu)先原則左胞,請(qǐng)求和響應(yīng)的參數(shù)都應(yīng)遵循約定,不然wsdl
文件生成是錯(cuò)誤的举户,這里踩了坑烤宙。。
Spring-WS服務(wù)端發(fā)布
spring-ws
像spring-mvc
一樣俭嘁,在集成到web項(xiàng)目時(shí)躺枕,前端有個(gè)servlet分發(fā)請(qǐng)求消息的概念。
這個(gè)servlet接受soap消息,通過映射轉(zhuǎn)發(fā)到后端的服務(wù)實(shí)現(xiàn)類方法中(Endpiont)
在請(qǐng)求進(jìn)來處理過程中拐云,可以添加罢猪,攔截器(Interceptor),異常處理器(ExceptionResolver)叉瘩。
通過攔截器可以做一些額外的定制功能膳帕,比如安全。通過異常處理器定制異常信息顯示房揭,處理等备闲。
這個(gè)servlet就是MessageDispatcher
,來看看官網(wǎng)給出的處理流程圖:
所以在需要對(duì)請(qǐng)求參數(shù)或者響應(yīng)參數(shù)做處理時(shí)捅暴,可以編寫對(duì)應(yīng)的攔截器進(jìn)行處理的恬砂。
現(xiàn)在,以一個(gè)簡單示例來發(fā)布一個(gè)webService
服務(wù)蓬痒。創(chuàng)建工程:spring-boot-webservice-server
泻骤。
0.引入POM依賴。
<!-- spirng ws 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<!-- 生成wsdl文件 -->
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
1.創(chuàng)建一個(gè)xsd
文件梧奢,用來描述請(qǐng)求和響應(yīng)的各實(shí)體信息狱掂。這里簡單以一個(gè)獲取作者信息為例子。
author.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.lqdev.cn/webservice"
targetNamespace="http://www.lqdev.cn/webservice" elementFormDefault="qualified">
<!-- 定義請(qǐng)求實(shí)體 -->
<xs:element name="authorRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- 定義響應(yīng)實(shí)體 -->
<xs:element name="authorResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="tns:author"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- 定義請(qǐng)求實(shí)體 -->
<xs:element name="authorListRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="nonce" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- 定義響應(yīng)實(shí)體 -->
<xs:element name="authorListResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="tns:author" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- 定義作者 信息 -->
<xs:complexType name="author">
<xs:sequence>
<xs:element name="name" type="xs:string" />
<!-- 愛好 列表形式 nillable=true 可為空 亲轨,maxOccurs=unbouned 無限 -->
<xs:element name="hobby" type="xs:string" nillable="true" maxOccurs="unbounded" />
<!-- 性別 枚舉類型 限定 -->
<xs:element name="sex" type="tns:sex" />
<!-- 生日 -->
<xs:element name="birthday" type="xs:string" />
<!-- 描述 -->
<xs:element name="description" type="xs:string" />
</xs:sequence>
</xs:complexType>
<!-- 枚舉類型 性別:男 女 -->
<xs:simpleType name="sex">
<xs:restriction base="xs:string">
<xs:enumeration value="male"/>
<xs:enumeration value="female"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
這里需要注意趋惨,請(qǐng)求和返回的名字是有要求的,兩個(gè)名字前面要一樣惦蚊,后綴分別是固定的配置器虾,默認(rèn)為Request和Response; 當(dāng)然可以通過requestSuffix
和responseSuffix
屬性來修改默認(rèn)值的,在配置小節(jié)會(huì)說到蹦锋。
關(guān)于xsd
規(guī)則兆沙,可以查看:http://www.w3school.com.cn/schema/index.asp。
2.根據(jù)XSD文件創(chuàng)建實(shí)體對(duì)象莉掂。這里直接使用maven
創(chuàng)建自動(dòng)生成葛圃。pom中加入插件:jaxb2-maven-plugin
。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>${project.basedir}/src/main/resources/</schemaDirectory>
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
<!-- 包名路徑 --> <packageName>cn.lqdev.learning.springboot.ws.webservice</packageName>
</configuration>
</plugin>
然后運(yùn)行下命令:mvn install
就會(huì)自動(dòng)創(chuàng)建了憎妙。正常情況下库正,添加后,xsd
文件有變動(dòng)厘唾,都會(huì)實(shí)時(shí)創(chuàng)建對(duì)應(yīng)實(shí)體對(duì)象的诀诊。此時(shí),生成的對(duì)象如下:
3.創(chuàng)建Endpoint服務(wù)阅嘶,有點(diǎn)類似Controller
属瓣,請(qǐng)求服務(wù)的入口载迄。
/**
* 創(chuàng)建endpoint 類似于創(chuàng)建controller了。
* @author oKong
*
*/
@Endpoint
public class AuthorEndpoint {
@PayloadRoot(namespace = WsConst.NAMESPACE_URI, localPart = "authorRequest")
@ResponsePayload
public AuthorResponse getAuthor(@RequestPayload AuthorRequest authorReq){
AuthorResponse resp = new AuthorResponse();
Author author = new Author();
author.setBirthday("1990-01-23");
author.setName("姓名:" + authorReq.getName());
author.setSex(Sex.FEMALE);
author.getHobby().addAll(Arrays.asList("電影","旅游"));
author.setDescription("描述:一枚趔趄的猿÷胀埽現(xiàn)在時(shí)間:" + new Date().getTime());
resp.setAuthor(author);
return resp;
}
@PayloadRoot(namespace = WsConst.NAMESPACE_URI, localPart = "authorListRequest")
@ResponsePayload
public AuthorListResponse getAuthorList(@RequestPayload AuthorListRequest request){
AuthorListResponse resp = new AuthorListResponse();
Author author = new Author();
author.setBirthday("1990-01-23");
author.setName("姓名:oKong");
author.setSex(Sex.FEMALE);
author.getHobby().addAll(Arrays.asList("電影","旅游"));
author.setDescription("描述:一枚趔趄的猿』っ粒現(xiàn)在時(shí)間:" + new Date().getTime());
resp.getAuthor().add(author);
resp.getAuthor().add(author);
return resp;
}
}
示例代碼,只是為了演示粗截,大部分信息都固定寫死了惋耙。實(shí)際開發(fā)中,可以加入各自的業(yè)務(wù)邏輯熊昌,引入相應(yīng)的service
類的妇智。
而且类咧,這里需要注意:
- 方法聲明上的
@PayloadRoot
標(biāo)注中的namespace
和localPart
分別就是wsdl中的targetNamespace
和soap
方法名稱。 @ResponsePayload
和@RequestPayload
這兩個(gè)標(biāo)注的用法,以及它們對(duì)應(yīng)的數(shù)據(jù)類型就是此前通過maven插件對(duì)wsdl定義生成的java類杠袱。
關(guān)于請(qǐng)求參數(shù)的類型截粗,是否需要加@RequestPayload
說明:
一般上袱巨,都是使用JAXB2
對(duì)象了适篙,也就是先前生成的實(shí)體對(duì)象。當(dāng)然蜂奸,有興趣的同學(xué)可以試試犁苏,其他的對(duì)象參數(shù),可以獲取到不同的參數(shù)值的扩所。
比如:
public void handle(@RequestPayload Element element)
一個(gè)org.w3c.dom.Element
對(duì)象围详。
public void handle(@RequestPayload DOMSource domSource, SoapHeader header)
這樣,能獲取到SOAP
的頭部信息祖屏。
其他相關(guān)用法助赞,可以查看此地址:https://docs.spring.io/spring-ws/docs/2.4.2.RELEASE/reference/#server-atEndpoint-methods
關(guān)于響應(yīng)的參數(shù),是否需要加@ResponsePayload
赐劣,一下是官網(wǎng)給出的說明信息:
這個(gè)有個(gè)坑:嘗試無參數(shù)請(qǐng)求時(shí),使用postman發(fā)送xml數(shù)據(jù)可以正常請(qǐng)求哩都,但使用spirng-ws
調(diào)用就調(diào)用不到了魁兼,嗯,我想應(yīng)該是我調(diào)用方法不多漠嵌。咐汞。⊙﹏⊙‖∣
4.創(chuàng)建配置類儒鹿,生效webservice服務(wù)化撕。
/**
* ws-配置
* @author oKong
*
*/
@EnableWs //開啟webService
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter{
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);//true 地址會(huì)進(jìn)行轉(zhuǎn)換,不然都是本地地址
//這里可以設(shè)置 請(qǐng)求的工廠類约炎,實(shí)現(xiàn)有兩個(gè):SaajSoapMessageFactory 和 AxiomSoapMessageFactory
//默認(rèn)是 SaajSoapMessageFactory
// servlet.setMessageFactoryBeanName(messageFactoryBeanName);
return new ServletRegistrationBean(servlet, "/ws/*");
}
//name 就是對(duì)應(yīng) wsdl名如 :/ws/author.wsdl
@Bean(name = "author")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema authorSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("AuthorPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setSchema(authorSchema);
wsdl11Definition.setTargetNamespace(WsConst.NAMESPACE_URI);
return wsdl11Definition;
}
//可自定義SaajSoapMessageFactory 然后指定其SOAP版本
@Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
//指定版本
messageFactory.setSoapVersion(SoapVersion.SOAP_11);//SoapVersion.SOAP_12
return messageFactory;
}
@Bean
public XsdSchema authorSchema() {
return new SimpleXsdSchema(new ClassPathResource("author.xsd"));
}
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
//可以自定義攔截器
}
}
常量類:WsConst.java
/**
* 常量類
* @author oKong
*
*/
public class WsConst {
public static final String NAMESPACE_URI = "http://www.lqdev.cn/webservice";
}
5.編寫啟動(dòng)類植阴。
/**
* web-service 簡單示例
*
* @author oKong
*
*/
@SpringBootApplication
@Slf4j
public class WebServiceApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(WebServiceApplication.class, args);
log.info("spring-boot-webservice-server-chapter33啟動(dòng)!");
}
}
6.啟動(dòng)應(yīng)用蟹瘾,訪問下:http://127.0.0.1:8090/ws/author.wsdl ,可以看見wsdl文件內(nèi)容了。
接著掠手,我們使用postman
調(diào)用下:POST http://127.0.0.1:8090/ws
說明已經(jīng)正常發(fā)布了憾朴。接下來,我們使用spring-ws
直接調(diào)用喷鸽。
Spirng-WS客戶端調(diào)用
創(chuàng)建一個(gè)新工程:spring-boot-webservice-client
0.引入POM依賴众雷。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
1.獲取wsdl文件,放入src\main\resources\schemas\
文件夾中做祝,同時(shí)加入maven
插件:maven-jaxb2-plugin
使其生成對(duì)應(yīng)實(shí)體列砾省。
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generatePackage>cn.lqdev.webservice</generatePackage>
<generateDirectory>${basedir}/src/main/java</generateDirectory>
<schemas>
<schema>
<fileset>
<!-- Defaults to schemaDirectory. -->
<directory>${basedir}/src/main/resources/schemas</directory>
<!-- Defaults to schemaIncludes. -->
<includes>
<include>*.wsdl</include>
</includes>
</fileset>
</schema>
</schemas>
</configuration>
</plugin>
wsdl文件就不貼了。目錄為:
生成后對(duì)應(yīng)實(shí)體類為:
注意:寫此文章前混槐,嘗試過使用cxf
進(jìn)行調(diào)用编兄,而調(diào)用過程中,發(fā)現(xiàn)請(qǐng)求的實(shí)體需要在包cn.lqdev.webservice
路徑下纵隔,不然校驗(yàn)不通過翻诉。所以為了兼容,我直接寫成此路徑了捌刮。對(duì)于spring ws
而言碰煌,包名可以自定義的。不知道cxf
是不是可以修改绅作,跟蹤了下源碼也沒有找到具體這個(gè)規(guī)則是怎么來的芦圾,不知道是不是和targetNamespace
的值http://www.lqdev.cn/webservice
有關(guān),有待測(cè)試俄认。
2.創(chuàng)建客戶端調(diào)用類个少。
/**
* 編寫客戶端 繼承WebServiceGatewaySupport 類 方便調(diào)用
* @author oKong
*
*/
public class WsAuthorClient extends WebServiceGatewaySupport{
/**
* 獲取作者信息
* @author oKong
*/
public AuthorResponse getAuthor(String name) {
AuthorRequest req = new AuthorRequest();
req.setName(name);
//使用 marshalSendAndReceive 進(jìn)行調(diào)用
return (AuthorResponse) getWebServiceTemplate().marshalSendAndReceive(req);
}
/**
* 獲取作者列表信息
* @author oKong
*/
public AuthorListResponse getAuthorList(){
AuthorListRequest request = new AuthorListRequest();
request.setNonce(UUID.randomUUID().toString());
return (AuthorListResponse) getWebServiceTemplate().marshalSendAndReceive(request);
}
}
此類,就是調(diào)用webservice服務(wù)的眯杏。
4.創(chuàng)建配置類.
/**
* 客戶端調(diào)用配置
* @author oKong
*
*/
@Configuration
public class WsClientConfig {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
//會(huì)掃描此類下面的對(duì)應(yīng)的 jaxb2實(shí)體類 因?yàn)槭鞘褂?Marshaller和 unmarshaller來進(jìn)行xml和bean直接轉(zhuǎn)換的
//具體是判斷此路徑下是否包含 ObjectFactory.class 文件
//設(shè)置 JAXBContext 對(duì)象
marshaller.setContextPath("cn.lqdev.webservice");
//或者使用 以下方式設(shè)置
// marshaller.setPackagesToScan(packagesToScan);
// marshaller.setClassesToBeBound(classesToBeBound);
return marshaller;
}
/*
* 創(chuàng)建bean
*/
@Bean
public WsAuthorClient wsClient(Jaxb2Marshaller marshaller) {
WsAuthorClient client = new WsAuthorClient();
//默認(rèn)對(duì)應(yīng)的ws服務(wù)地址 client請(qǐng)求中還能動(dòng)態(tài)修改的
client.setDefaultUri("http://127.0.0.1:8090/ws");
client.setMarshaller(marshaller);//指定轉(zhuǎn)換類
client.setUnmarshaller(marshaller);
return client;
}
}
關(guān)于marshaller
和 unmarshaller
解析xml和讀取xml相關(guān)知識(shí)夜焦,沒有過多了解,感興趣的可以自行搜索相關(guān)資料下岂贩。
5.創(chuàng)建示例控制層茫经,調(diào)用各服務(wù)接口。
/**
* 簡單調(diào)用示例
* @author oKong
*
*/
@RestController
@RequestMapping("/author")
public class DemoController {
@Autowired
WsAuthorClient authorClient;
@GetMapping("/get")
public AuthorResponse getAuthor(String name) {
return authorClient.getAuthor(name);
}
@GetMapping("/list")
public AuthorListResponse getAuthorList() {
return authorClient.getAuthorList();
}
}
6.修改端口號(hào)為:8096萎津,同時(shí)啟動(dòng)應(yīng)用卸伞。
server.port=8096
使用Postman
,訪問:http://127.0.0.1:8096/author/get?name=程序員
正常情況下可以看見以下返回內(nèi)容:
說明調(diào)用成功了。
訪問下列表:http://127.0.0.1:8096/author/list
簡單使用CXF調(diào)用webService
接下類锉屈,嘗試下使用cxf
來訪問下服務(wù)荤傲。
0.引入cxf
相關(guān)依賴。
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
1.controller類新增一個(gè)方法颈渊,使用cxf方式調(diào)用服務(wù)遂黍。
@GetMapping("/cxf/{method}")
public Object cxf(@PathVariable String method,String name) throws Exception{
//獲取客戶端工廠類
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
//創(chuàng)建client對(duì)象
Client client = dcf.createClient("http://127.0.0.1:8090/ws/author.wsdl");
AuthorListRequest listReq = new AuthorListRequest();
listReq.setNonce(UUID.randomUUID().toString());
AuthorRequest req = new AuthorRequest();
req.setName(name);
//調(diào)用 第一個(gè)方法是operation 值终佛,即調(diào)用方法,
//其后是調(diào)用參數(shù)妓湘。
Object[] objects = new Object[0];
//相關(guān) operation值 可以根據(jù) client.getEndpoint().getBinding().getBindingInfo().getOperations(); 獲取
//有興趣可以看下 client.getEndpoint().getBinding().getBindingInfo()提供的一些方法查蓉。
//這里就簡單的判斷了
if("authorList".equalsIgnoreCase(method)) {
objects = client.invoke("authorList", listReq);
} else {
objects = client.invoke("author", req);
}
//返回的對(duì)象objects[0]即為返回的值
return objects[0];
}
這里需要注意:對(duì)應(yīng)的實(shí)體類,需要符合wsdl文件中解析出來的type Classes 對(duì)應(yīng)上榜贴,本例子為:cn.lqdev.webservice.AuthorListRequest
豌研,猜猜應(yīng)該和targetNamespace
值有關(guān),不然會(huì)出現(xiàn)以下類似提示:
Part {http://www.lqdev.cn/webservice}authorListRequest should be of type cn.lqdev.webservice.AuthorListRequest, not cn.lqdev.learning.webservice.AuthorListRequest
最后發(fā)現(xiàn)使用cxf
也很簡單呀唬党,下次試試鹃共。是利用JAX-WS
規(guī)范的。
2.重啟應(yīng)用驶拱,訪問下:http://127.0.0.1:8096/author/cxf/author?name=趔趄的猿 最后效果是一樣的霜浴。
訪問:http://127.0.0.1:8096/author/cxf/authorList
有待補(bǔ)充
以上只是基于官方文檔,簡單的示例了一遍蓝纲,具體一些高級(jí)用法以及相關(guān)安全校驗(yàn)阴孟、過濾器等等,沒有過多涉及的税迷。之后有時(shí)間再填坑吧永丝,畢竟這個(gè)用的真的不多呀。
參考資料
總結(jié)
本章節(jié)主要簡單介紹了
spring-ws
的使用箭养。原本是沒有打算寫關(guān)于WebService
相關(guān)的慕嚷。只是機(jī)緣巧合下剛好有個(gè)對(duì)接系統(tǒng)需要用上,就臨時(shí)嘗試一下了毕泌。還有很多深入的功能喝检,就沒有過多涉及了。等到時(shí)候真正開始對(duì)接時(shí)撼泛,有碰到一些問題或者有些知識(shí)點(diǎn)補(bǔ)充的挠说,再來補(bǔ)充吧。畢竟愿题,我想現(xiàn)在除了舊系統(tǒng)和政府部門的系統(tǒng)损俭,應(yīng)該很少再去開發(fā)webservice
服務(wù)了吧。官網(wǎng)文檔大致看了下抠忘,也確實(shí)覺得有點(diǎn)復(fù)雜呀撩炊,不知道是不是理解能力問題外永,⊙﹏⊙‖∣崎脉。理論上,按著規(guī)則走伯顶,問題應(yīng)該也不是很大囚灼。就是一些比如無參數(shù)如何調(diào)用骆膝,或者返回參數(shù)節(jié)點(diǎn)自定義問題,這些理論上都可以使用提供的攔截器來完成的灶体。有問題阅签,還是建議查看官網(wǎng)吧,真的比較詳細(xì)蝎抽。最后看了cxf
政钟,也比較簡單。下一篇就來寫寫使用cxf
來發(fā)布webservice
樟结,多嘗試幾種方式~
最后
目前互聯(lián)網(wǎng)上很多大佬都有
SpringBoot
系列教程养交,如有雷同,請(qǐng)多多包涵了瓢宦。原創(chuàng)不易碎连,碼字不易,還希望大家多多支持驮履。若文中有所錯(cuò)誤之處鱼辙,還望提出,謝謝玫镐。
老生常談
- 個(gè)人QQ:
499452441
- 微信公眾號(hào):
lqdevOps
個(gè)人博客:http://blog.lqdev.cn
完整示例:https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-33
原文地址:http://blog.lqdev.cn/2018/11/09/springboot/chapter-thirty-three/