
本指南將引導(dǎo)您完成使用 Spring 使用基于 SOAP 的 Web 服務(wù)的過程。
您將構(gòu)建一個客戶端,該客戶端使用肥皂?.您可以通過以下方式了解有關(guān)國家/地區(qū)服務(wù)的更多信息并自行運行服務(wù)本指南.
【資料圖】
該服務(wù)提供國家數(shù)據(jù)。您將能夠根據(jù)國家/地區(qū)的名稱查詢有關(guān)該國家/地區(qū)的數(shù)據(jù)。
像大多數(shù)春天一樣入門指南,您可以從頭開始并完成每個步驟,也可以繞過您已經(jīng)熟悉的基本設(shè)置步驟。無論哪種方式,您最終都會得到工作代碼。
要從頭開始,請繼續(xù)從 Spring 初始化開始.
要跳過基礎(chǔ)知識,請執(zhí)行以下操作:
下載?并解壓縮本指南的源存儲庫,或使用吉特:git clonehttps://github.com/spring-guides/gs-consuming-web-service.git
光盤成gs-consuming-web-service/initial
跳轉(zhuǎn)到基于 WSDL 生成域?qū)ο?完成后,您可以根據(jù) 中的代碼檢查結(jié)果。??gs-consuming-web-service/complete?
?
如果您閱讀生成 SOAP Web 服務(wù)?,您可能想知道為什么本指南不使用?Spring Boot 啟動器僅適用于服務(wù)器端 Web 服務(wù)。該啟動器引入了諸如嵌入式Tomcat之類的東西,而進行網(wǎng)絡(luò)呼叫不需要這些東西。? |
按照配套指南或克隆存儲 庫并從其目錄運行服務(wù)(例如,使用 )。您可以通過在瀏覽器中訪問來驗證它是否有效。如果不這樣做,稍后在 JAXB 工具的構(gòu)建中看到一個令人困惑的異常。??mvn spring-boot:run?
???complete?
???http://localhost:8080/ws/countries.wsdl?
?
對于所有 Spring 應(yīng)用程序,您應(yīng)該從Spring Initializr.Initializr 提供了一種快速的方法來拉入應(yīng)用程序所需的所有依賴項,并為您完成大量設(shè)置。此示例只需要 Spring Web Services 依賴項。
初始化項目:
導(dǎo)航到https://start.spring.io.此服務(wù)拉入應(yīng)用程序所需的所有依賴項,并為您完成大部分設(shè)置。選擇 Gradle 或 Maven 以及您要使用的語言。本指南假定您選擇了 Java。單擊“依賴關(guān)系”,然后選擇“Spring Web 服務(wù)”。單擊生成。下載生成的 ZIP 文件,該文件是配置了您選擇的 Web 應(yīng)用程序的存檔。如果您的 IDE 集成了 Spring Initializr,則可以從 IDE 完成此過程。 |
您也可以從 Github 分叉項目,然后在 IDE 或其他編輯器中打開它。 |
Spring Initializr 創(chuàng)建的構(gòu)建文件需要為本指南做相當(dāng)多的工作。此外,對(對于Maven)和(對于Gradle)的修改也有很大不同。??pom.xml?
???build.gradle?
?
對于 Maven,您需要添加依賴項、配置文件和 WSDL 生成插件。
以下清單顯示了需要在 Maven 中添加的依賴項:
org.springframework.boot spring-boot-starter-web-services org.springframework.boot spring-boot-starter-tomcat
以下清單顯示了如果您希望 Maven 與 Java 11 配合使用,則需要在 Maven 中添加的配置文件:
java11 [11,) org.glassfish.jaxb jaxb-runtime
這基于 WSDL 生成域?qū)ο蟛糠纸榻B WSDL 生成插件。
下面的清單顯示了最終文件:??pom.xml?
?
4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.1 com.example consuming-web-service-complete 0.0.1-SNAPSHOT consuming-web-service-complete Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web-services org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-test test java11 [11,) org.glassfish.jaxb jaxb-runtime org.springframework.boot spring-boot-maven-plugin org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.14.0 generate WSDL com.example.consumingwebservice.wsdl http://localhost:8080/ws/countries.wsdl
對于 Gradle,您需要添加依賴項、配置、部分和 WSDL 生成插件。??bootJar?
?
以下清單顯示了您需要在 Gradle 中添加的依賴項:
implementation ("org.springframework.boot:spring-boot-starter-web-services") { exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"}implementation "org.springframework.ws:spring-ws-core"http:// For Java 11:implementation "org.glassfish.jaxb:jaxb-runtime"implementation(files(genJaxb.classesDir).builtBy(genJaxb))jaxb "com.sun.xml.bind:jaxb-xjc:2.1.7"
請注意Tomcat的排除。如果允許 Tomcat 在此版本中運行,則會出現(xiàn)與提供國家/地區(qū)數(shù)據(jù)的 Tomcat 實例的端口沖突。
以下清單顯示了您需要在 Gradle 中添加的部分:??bootJar?
?
bootJar { baseName = "gs-consuming-web-service" version = "0.0.1"}
這基于 WSDL 生成域?qū)ο蟛糠纸榻B WSDL 生成插件。
下面的清單顯示了最終文件:??build.gradle?
?
plugins { id "org.springframework.boot" version "2.7.1" id "io.spring.dependency-management" version "1.0.11.RELEASE" id "java"}group = "com.example"version = "0.0.1-SNAPSHOT"sourceCompatibility = "1.8"http:// tag::configurations[]configurations { jaxb}// end::configurations[]repositories { mavenCentral()}// tag::wsdl[]task genJaxb { ext.sourcesDir = "${buildDir}/generated-sources/jaxb" ext.classesDir = "${buildDir}/classes/jaxb" ext.schema = "http://localhost:8080/ws/countries.wsdl" outputs.dir classesDir doLast() { project.ant { taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: configurations.jaxb.asPath mkdir(dir: sourcesDir) mkdir(dir: classesDir) xjc(destdir: sourcesDir, schema: schema, package: "com.example.consumingwebservice.wsdl") { arg(value: "-wsdl") produces(dir: sourcesDir, includes: "**/*.java") } javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true, debugLevel: "lines,vars,source", classpath: configurations.jaxb.asPath) { src(path: sourcesDir) include(name: "**/*.java") include(name: "*.java") } copy(todir: classesDir) { fileset(dir: sourcesDir, erroronmissingdir: false) { exclude(name: "**/*.java") } } } }}// end::wsdl[]dependencies {// tag::dependency[] implementation ("org.springframework.boot:spring-boot-starter-web-services") { exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat" } implementation "org.springframework.ws:spring-ws-core" // For Java 11: implementation "org.glassfish.jaxb:jaxb-runtime" implementation(files(genJaxb.classesDir).builtBy(genJaxb)) jaxb "com.sun.xml.bind:jaxb-xjc:2.1.7"http:// end::dependency[] testImplementation("org.springframework.boot:spring-boot-starter-test")}test { useJUnitPlatform()}// tag::bootjar[]bootJar { baseName = "gs-consuming-web-service" version = "0.0.1"}// end::bootjar[]
SOAP Web 服務(wù)的接口在??WSDL??.JAXB 提供了一種從 WSDL(或者更確切地說,WSDL 部分中包含的 XSD)生成 Java 類的方法。您可以在 中找到國家/地區(qū)服務(wù)的 WSDL。??
???http://localhost:8080/ws/countries.wsdl?
?
要從 Maven 中的 WSDL 生成 Java 類,您需要以下插件設(shè)置:
org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.14.0 generate WSDL com.example.consumingwebservice.wsdl http://localhost:8080/ws/countries.wsdl
此設(shè)置將為在指定 URL 中找到的 WSDL 生成類,并將這些類放在包中。要生成該代碼,請運行,然后查看是否要檢查它是否有效。??com.example.consumingwebservice.wsdl?
???./mvnw compile?
???target/generated-sources?
?
要對 Gradle 執(zhí)行相同的操作,您需要在構(gòu)建文件中提供以下內(nèi)容:
task genJaxb { ext.sourcesDir = "${buildDir}/generated-sources/jaxb" ext.classesDir = "${buildDir}/classes/jaxb" ext.schema = "http://localhost:8080/ws/countries.wsdl" outputs.dir classesDir doLast() { project.ant { taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: configurations.jaxb.asPath mkdir(dir: sourcesDir) mkdir(dir: classesDir) xjc(destdir: sourcesDir, schema: schema, package: "com.example.consumingwebservice.wsdl") { arg(value: "-wsdl") produces(dir: sourcesDir, includes: "**/*.java") } javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true, debugLevel: "lines,vars,source", classpath: configurations.jaxb.asPath) { src(path: sourcesDir) include(name: "**/*.java") include(name: "*.java") } copy(todir: classesDir) { fileset(dir: sourcesDir, erroronmissingdir: false) { exclude(name: "**/*.java") } } } }}
由于 Gradle (還)沒有 JAXB 插件,它涉及一個 Ant 任務(wù),這使得它比 Maven 更復(fù)雜一些。要生成該代碼,請運行,然后查看是否要檢查它是否有效。??./gradlew compileJava?
???build/generated-sources?
?
在這兩種情況下,JAXB 域?qū)ο笊蛇^程都已連接到構(gòu)建工具的生命周期中,因此一旦成功構(gòu)建,就無需運行任何額外的步驟。
要創(chuàng)建 Web 服務(wù)客戶端,您必須擴展WebServiceGatewaySupport對操作進行類化和編碼,如以下示例(來自 )所示:??src/main/java/com/example/consumingwebservice/CountryClient.java?
?
package com.example.consumingwebservice;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.ws.client.core.support.WebServiceGatewaySupport;import org.springframework.ws.soap.client.core.SoapActionCallback;import com.example.consumingwebservice.wsdl.GetCountryRequest;import com.example.consumingwebservice.wsdl.GetCountryResponse;public class CountryClient extends WebServiceGatewaySupport { private static final Logger log = LoggerFactory.getLogger(CountryClient.class); public GetCountryResponse getCountry(String country) { GetCountryRequest request = new GetCountryRequest(); request.setName(country); log.info("Requesting location for " + country); GetCountryResponse response = (GetCountryResponse) getWebServiceTemplate() .marshalSendAndReceive("http://localhost:8080/ws/countries", request, new SoapActionCallback( "http://spring.io/guides/gs-producing-web-service/GetCountryRequest")); return response; }}
客戶端包含一個執(zhí)行實際 SOAP 交換的方法 ()。??getCountry?
?
在此方法中,和 類都派生自 WSDL,并在 JAXB 生成過程中生成(在??GetCountryRequest?
???GetCountryResponse?
???基于 WSDL 生成域?qū)ο??).它創(chuàng)建請求對象并使用參數(shù)(國家/地區(qū)名稱)對其進行設(shè)置。打印出國家名稱后,它使用??GetCountryRequest?
???country?
???WebServiceTemplate??由基類提供,用于執(zhí)行實際的 SOAP 交換。它傳遞請求對象(以及傳遞??WebServiceGatewaySupport?
???GetCountryRequest?
???SoapActionCallback?
???肥皂??帶有請求的標(biāo)頭),因為 WSDL 描述它在元素中需要此標(biāo)頭。它將響應(yīng)強制轉(zhuǎn)換為對象,然后返回該對象。??
???GetCountryResponse?
?
Spring WS使用Spring Framework的OXM模塊,該模塊具有序列化和反序列化XML請求的功能,如以下示例(來自)所示:??Jaxb2Marshaller?
???src/main/java/com/example/consumingwebservice/CountryConfiguration.java?
?
package com.example.consumingwebservice;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.oxm.jaxb.Jaxb2Marshaller;@Configurationpublic class CountryConfiguration { @Bean public Jaxb2Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); // this package must match the package in thespecified in // pom.xml marshaller.setContextPath("com.example.consumingwebservice.wsdl"); return marshaller; } @Bean public CountryClient countryClient(Jaxb2Marshaller marshaller) { CountryClient client = new CountryClient(); client.setDefaultUri("http://localhost:8080/ws"); client.setMarshaller(marshaller); client.setUnmarshaller(marshaller); return client; }}
指向生成的域?qū)ο蟮募希⑹褂盟鼈冊?XML 和 POJO 之間進行序列化和反序列化。??marshaller?
?
使用前面所示的國家/地區(qū)服務(wù)的 URI 創(chuàng)建和配置。它還配置為使用 JAXB 編組器。??countryClient?
?
此應(yīng)用程序打包為從控制臺運行并檢索給定國家/地區(qū)名稱的數(shù)據(jù),如以下列表 (from ) 所示:??src/main/java/com/example/consumingwebservice/ConsumingWebServiceApplication.java?
?
package com.example.consumingwebservice;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import com.example.consumingwebservice.wsdl.GetCountryResponse;@SpringBootApplicationpublic class ConsumingWebServiceApplication { public static void main(String[] args) { SpringApplication.run(ConsumingWebServiceApplication.class, args); } @Bean CommandLineRunner lookup(CountryClient quoteClient) { return args -> { String country = "Spain"; if (args.length > 0) { country = args[0]; } GetCountryResponse response = quoteClient.getCountry(country); System.err.println(response.getCountry().getCurrency()); }; }}
該方法遵循??main()?
?SpringApplication幫助程序類,作為其方法的參數(shù)提供。這告訴 Spring 從中讀取注釋元數(shù)據(jù),并將其作為 Spring 應(yīng)用程序上下文中的組件進行管理。??CountryConfiguration.class?
???run()?
???CountryConfiguration?
?
此應(yīng)用程序是硬編碼以查找“西班牙”。在本指南的后面部分,您將看到如何在不編輯代碼的情況下輸入不同的符號。 |
您可以使用 Gradle 或 Maven 從命令行運行應(yīng)用程序。您還可以構(gòu)建一個包含所有必需依賴項、類和資源的可執(zhí)行 JAR 文件并運行該文件。通過構(gòu)建可執(zhí)行 jar,可以輕松地在整個開發(fā)生命周期中跨不同環(huán)境等將服務(wù)作為應(yīng)用程序進行交付、版本控制和部署。
如果使用 Gradle,則可以使用 .或者,您可以使用 JAR 文件生成 JAR 文件,然后運行該文件,如下所示:??./gradlew bootRun?
???./gradlew build?
?
java -jar build/libs/gs-consuming-web-service-0.1.0.jar
如果使用 Maven,則可以使用 運行應(yīng)用程序?;蛘撸梢允褂?JAR 文件生成 JAR 文件,然后運行該文件,如下所示:??./mvnw spring-boot:run?
???./mvnw clean package?
?
java -jar target/gs-consuming-web-service-0.1.0.jar
此處描述的步驟將創(chuàng)建一個可運行的 JAR。你也可以構(gòu)建經(jīng)典 WAR 文件. |
將顯示日志記錄輸出。該服務(wù)應(yīng)在幾秒鐘內(nèi)啟動并運行。
以下清單顯示了初始響應(yīng):
Requesting country data for SpainSpain ...
您可以通過運行以下命令插入其他國家/地區(qū):
java -jar build/libs/gs-consuming-web-service-0.1.0.jar Poland
然后,響應(yīng)將更改為以下內(nèi)容:
Requesting location for PolandPoland ...
祝賀!您剛剛開發(fā)了一個客戶端,用于在 Spring 中使用基于 SOAP 的 Web 服務(wù)。
標(biāo)簽: 應(yīng)用程序 是否有效 配置文件