1. 程式人生 > >Spring Boot整合spring-ws開發web service

Spring Boot整合spring-ws開發web service

新增依賴

spring boot的工程,除了spring boot外還需要新增spring-ws和wsdl4j的依賴,當然後面生成程式碼還需要新增maven的jaxb2外掛。

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-ws</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>wsdl4j</groupId>
  7. <artifactId>
    wsdl4j</artifactId>
  8. </dependency>

編寫schema檔案

spring-ws的釋出,都是以一個schema檔案(xsd)定義開始的,它描述了web service的引數以及返回的資料。

下面是官方示例給出的countries.xsd,這裡我們也以它為例,當然名稱空間改掉了,因為等會jaxb2外掛生成程式碼是以它來確定包名的:

  1. <xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:tns="http://www.dexcoder.com/ws"
  2. targetNamespace="http://www.dexcoder.com/ws"
    elementFormDefault="qualified">
  3. <xs:elementname="getCountryRequest">
  4. <xs:complexType>
  5. <xs:sequence>
  6. <xs:elementname="name"type="xs:string"/>
  7. </xs:sequence>
  8. </xs:complexType>
  9. </xs:element>
  10. <xs:elementname="getCountryResponse">
  11. <xs:complexType>
  12. <xs:sequence>
  13. <xs:elementname="country"type="tns:country"/>
  14. </xs:sequence>
  15. </xs:complexType>
  16. </xs:element>
  17. <xs:complexTypename="country">
  18. <xs:sequence>
  19. <xs:elementname="name"type="xs:string"/>
  20. <xs:elementname="population"type="xs:int"/>
  21. <xs:elementname="capital"type="xs:string"/>
  22. <xs:elementname="currency"type="tns:currency"/>
  23. </xs:sequence>
  24. </xs:complexType>
  25. <xs:simpleTypename="currency">
  26. <xs:restrictionbase="xs:string">
  27. <xs:enumerationvalue="GBP"/>
  28. <xs:enumerationvalue="EUR"/>
  29. <xs:enumerationvalue="PLN"/>
  30. </xs:restriction>
  31. </xs:simpleType>
  32. </xs:schema>

新增maven的jaxb2外掛來生成程式碼

jaxb2外掛可以根據描述的xsd檔案來幫我們生成相應的ws程式碼,具體配置如下:

  1. <plugin>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-maven-plugin</artifactId>
  4. </plugin>
  5. <plugin>
  6. <groupId>org.codehaus.mojo</groupId>
  7. <artifactId>jaxb2-maven-plugin</artifactId>
  8. <version>1.6</version>
  9. <executions>
  10. <execution>
  11. <id>xjc</id>
  12. <goals>
  13. <goal>xjc</goal>
  14. </goals>
  15. </execution>
  16. </executions>
  17. <configuration>
  18. <schemaDirectory>${project.basedir}/src/main/resources//schema</schemaDirectory>
  19. <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
  20. <clearOutputDir>false</clearOutputDir>
  21. </configuration>
  22. </plugin>

配置好外掛然後install一下,這樣web service需要的服務端程式碼就已經幫我們生成好了,根據上面的xsd,生成的程式碼在com.dexcoder.ws包下。

生成的程式碼

編寫Endpoint

我們就不再像spring-ws官方那樣再建一個Repository了,這裡直接返回。需要注意PayloadRoot註解當中的namespacelocalPart需要和xsd中對應。

  1. @Endpoint
  2. publicclassCountryEndpoint{
  3. privatestaticfinalString NAMESPACE_URI ="http://www.dexcoder.com/ws";
  4. @PayloadRoot(namespace= NAMESPACE_URI, localPart ="getCountryRequest")
  5. @ResponsePayload
  6. publicGetCountryResponse getCountry(@RequestPayloadGetCountryRequest request){
  7. GetCountryResponse response =newGetCountryResponse();
  8. Country poland =newCountry();
  9. poland.setName("Poland-"+ request.getName());
  10. poland.setCapital("Warsaw");
  11. poland.setCurrency(Currency.PLN);
  12. poland.setPopulation(38186860);
  13. response.setCountry(poland);
  14. return response;
  15. }
  16. }

在spring boot中配置web service

在spring boot中配置spring-ws十分簡單,畢竟是同一家的東西,相容性應該沒的說。程式碼如下:

  1. @EnableWs
  2. @Configuration
  3. publicclassWebServiceConfigextendsWsConfigurerAdapter{
  4. @Bean
  5. publicServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext){
  6. MessageDispatcherServlet servlet =newMessageDispatcherServlet();
  7. servlet.setApplicationContext(applicationContext);
  8. servlet.setTransformWsdlLocations(true);
  9. returnnewServletRegistrationBean(servlet,"/ws/*");
  10. }
  11. @Bean(name ="countries")
  12. publicDefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema){
  13. DefaultWsdl11Definition wsdl11Definition =newDefaultWsdl11Definition();
  14. wsdl11Definition.setPortTypeName("CountriesPort");
  15. wsdl11Definition.setSchema(countriesSchema);
  16. return wsdl11Definition;
  17. }
  18. @Bean
  19. publicXsdSchema countriesSchema(){
  20. returnnewSimpleXsdSchema(newClassPathResource("schema/countries.xsd"));
  21. }
  22. }

到這裡spring-ws的所有配置和工作都已經完成了,上面的DefaultWsdl11Definitionid預設就是釋出的ws的訪問路徑。

啟動專案

最後一步當然是啟動專案了,這裡依然使用spring boot的啟動方式:

  1. @SpringBootApplication
  2. publicclassApplicationStartup{
  3. publicstaticvoid main(String[] args){
  4. SpringApplication.run(ApplicationStartup.class);
  5. }
  6. }

啟動後訪問 http://localhost:8080/ws/countries.wsdl 發現web service已經成功釋出了。

spring-ws-wsdl

這裡要注意一下spring-ws釋出的web service是以後綴.wsdl訪問的,跟傳統的?wsdl不大一樣,也看過它的原始碼,發現是在判斷後綴時寫死的,所以沒辦法配置修改了。

還有就是spring-ws實際上把釋出wsdl和真正的服務實現Endpoint分開了,如果你的Endpoint不正確,很可能會出現瀏覽器訪問.wsdl地址看起來正常而客戶端呼叫卻出現Not Found 404的錯誤。