javascript
SpringBoot整合spring-ws开发webservice接口(全流程详细教程)
場景
spring-ws
spring-ws官網:
https://spring.io/projects/spring-ws
SpringWebServices(Spring-WS)是Spring社區(qū)的一個產品,專注于創(chuàng)建文檔驅動的Web服務。SpringWebServices旨在促進契約優(yōu)先的SOAP服務開發(fā),允許使用多種操作XML有效負載的方式之一創(chuàng)建靈活的Web服務。該產品基于Spring本身,這意味著您可以使用Spring概念,例如依賴注入作為Web服務的一個組成部分。
Soap
SOAP(Simple Object AccessProtocol)簡單對象訪問協(xié)議。它是輕型協(xié)議,用于分散的、分布式計算環(huán)境中交換信息。SOAP有助于以獨立于平臺的方式訪問對象、服務和服務器。它借助于XML,提供了HTTP所需的擴展。
Soap與Http區(qū)別
都是底層的通信協(xié)議,請求包的格式不同,soap包是XML格式,http純文本格式
soap 的 可以傳遞結構化的 數(shù)據(jù),http只能傳輸純文本數(shù)據(jù);
WSDL
WSDL(Web服務描述語言,Web Services Description Language)是為描述Web服務發(fā)布的XML格式。
XSD
XML Schema Definition縮寫。
XML Schema 是基于 XML 的 DTD 替代者。
XML Schema 可描述 XML 文檔的結構。
XML Schema 語言也可作為 XSD(XML Schema Definition)來引用。
XSD教程:菜鳥教程
http://www.runoob.com/schema/schema-intro.html
實現(xiàn)
添加依賴
除了springboot的基本依賴,還要添加spring-ws以及wsdl4j的依賴。
打開項目的pom.xml
這里為了設置打包時去掉tomcat的jar包。
?<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions> </dependency><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId> </dependency>添加插件
為了能實現(xiàn)根據(jù)xsd文件自動生成代碼,還要添加maven的jaxb2插件。
打開pom.xml
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork></configuration></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/xsd/</schemaDirectory><outputDirectory>${project.basedir}/src/main/java</outputDirectory><clearOutputDir>false</clearOutputDir><encoding>utf-8</encoding></configuration></plugin></plugins><finalName></finalName><resources><resource><directory>src/main/resources</directory></resource><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource></resources></build>將下面這部分代碼放在如上的位置:
?
<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/xsd/</schemaDirectory><outputDirectory>${project.basedir}/src/main/java</outputDirectory><clearOutputDir>false</clearOutputDir><encoding>utf-8</encoding></configuration></plugin>注:
1.${project.basedir}? 是內置屬性,表示項目根目錄,即包含pom.xml文件的目錄。
2.可以通過<schemaDirectory>標簽指明xsd文件的位置。比如這里就是
3.可以通過?<outputDirectory>來指定jaxb2根據(jù)xsd文件生成實體類的位置
這里就是src/main/java下,然后jaxb2插件生成代碼是以命名空間來確定包名。
比如命名空間是http://test.com/webservice/pda
那么就會在src/main/java下生成com/test/webservice/pda目錄,并在此目錄下生成對應代碼。
4.可以通過<clearOutputDir>設置重新生成代碼時時候清除輸出目錄,默認是true,這里設置為false,要注意如果后期需要修改xsd文件并且可能會導致有重名的實體類時,修改為true。
?????????????????????
編寫schema文件/xsd文件
spring-ws的發(fā)布,都是以一個schema文件(xsd)定義開始的,它描述了web service的參數(shù)以及返回的數(shù)據(jù)。
在上面插件里指明的xsd所在目錄下,新建xsd文件,后綴名是.xsd
?
xsd文件示例代碼:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.com/webservice/pda"targetNamespace="http://test.com/webservice/pda" elementFormDefault="qualified"><!--登錄方法--><xs:element name="PdaLoginRequest"><xs:complexType><xs:sequence><xs:element name="username" type="xs:string"/><xs:element name="password" type="xs:string"/></xs:sequence></xs:complexType></xs:element><!--登錄響應--><xs:element name="PdaLoginResponse"><xs:complexType><xs:sequence><xs:element name="request-result" type="tns:LoginRequestResult"/><xs:element name="menu-result" type="tns:MenuList"/></xs:sequence></xs:complexType></xs:element><xs:complexType name="MenuList"><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" name="menu" nillable="true" type="tns:Menu"/></xs:sequence></xs:complexType><xs:complexType name="Menu"><xs:sequence><xs:element? name="menu" type="xs:string"/><xs:element? name="url" type="xs:string"/></xs:sequence></xs:complexType><!--登錄響應結果--><xs:complexType name="LoginRequestResult"><xs:sequence><xs:element name="request_result" type="xs:boolean"/><xs:element name="result_desc" type="xs:string"/></xs:sequence></xs:complexType></xs:schema>?
注意將:xmlns:tns="http://test.com/webservice/pda"和targetNamespace="http://test.com/webservice/pda"改為自己的命名空間。
這里是實現(xiàn)一個簡單的登錄請求與相應。登錄請求時傳遞兩個參數(shù)username和password。
?<xs:element name="username" type="xs:string"/>表示是string類型的username。
string是自帶類型,如果要使用自定義類型,要使用登錄響應中的類似這樣:
?<xs:element name="request-result" type="tns:LoginRequestResult"/>
然后登錄后的響應是有兩個自定義屬性。
第一個request-result表示請求結果。請求結果里面有是否請求成功的布爾值屬性和請求結果。
?<!--登錄響應結果--><xs:complexType name="LoginRequestResult"><xs:sequence><xs:element name="request_result" type="xs:boolean"/><xs:element name="result_desc" type="xs:string"/></xs:sequence></xs:complexType>第二個是登錄成功后不同用戶根據(jù)不同的權限返回不同的菜單List。
? <xs:complexType name="MenuList"><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" name="menu" nillable="true" type="tns:Menu"/></xs:sequence></xs:complexType><xs:complexType name="Menu"><xs:sequence><xs:element? name="menu" type="xs:string"/><xs:element? name="url" type="xs:string"/></xs:sequence></xs:complexType>而每一個MenuList的屬性又是一個自定義Menu,而每一個自定義Menu有兩個屬性。
一個是菜單的名字,一個是點擊菜單后返回的url。
使用插件生成代碼
jaxb2插件可以根據(jù)描述的xsd文件來幫我們生成相應的ws代碼
使用Maven的install命令或者package就可以在設置的輸出的目錄下生成對應的實體類代碼。
這里以IDEA為例,打開Maven命令面板。
雙擊運行install或者package會生成代碼。
來到配置輸出的目錄下
?編寫Endpoint
SpringBoot的Endpoint主要是用來監(jiān)控應用服務的運行狀況,并集成在Mvc中提供查看接口。簡單點說相當于一個url服務,就是將請求時的url與后臺響應的方法對應起來。
其編寫方法類似于Controller。
新建webservice包,包下新建EndPoint
package com.ws.api.webservice; import com.ws.api.sys.service.LoginService; import com.ws.api.sys.service.ProduceReceiveService; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload;import javax.annotation.Resource; import java.util.List;/*** PDA接口切點* @author* @version badao* @see* @since**/ @Endpoint public class PdaEndpoint {@Resourceprivate LoginService loginService;//引入用戶mapperprivate static final String NAMESPACE_URI = "http://test.com/webservice/pda";@PayloadRoot(namespace = NAMESPACE_URI, localPart = "PdaLoginRequest")@ResponsePayloadpublic PdaLoginResponse statusFeedbacke(@RequestPayload PdaLoginRequest request){String username = request.getUsername();String password = request.getPassword();return loginService.loginRequest(username,password);}}注:
其中@Endpoint作用類似于@Controller
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "PdaLoginRequest")聲明命名空間,要與xsd文件中的一致。
@ResponsePayload 必加,方法的返回類型要與xsd定義的請求類型一致,方法參數(shù)里請求類型要與xsd文件中的一致。
我們可以通過request對象的get方法獲取相應的請求參數(shù)。
然后將service方法中的返回類型設置為相應的響應類型。
LoginService 代碼:
package com.ws.api.sys.service;import com.test.webservice.pda.PdaLoginResponse; import org.springframework.stereotype.Service;@Service public interface LoginService {PdaLoginResponse loginRequest(String username, String password); }serviceImpl代碼:
package com.ws.api.sys.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.wongoing.webservice.pda.LoginRequestResult; import com.wongoing.webservice.pda.Menu; import com.test.webservice.pda.MenuList; import com.test.webservice.pda.PdaLoginResponse; import com.ws.api.sys.entity.SysUser; import com.ws.api.sys.mapper.SysUserMapper; import com.ws.api.sys.service.LoginService; import com.ws.api.sys.shiro.ShiroHelper;import org.springframework.stereotype.Service;import javax.annotation.Resource; import java.util.List;@Service public class LoginServiceImpl implements LoginService {@Resourceprivate SysUserMapper sysUserMapper;//引入用戶mapper@Overridepublic PdaLoginResponse loginRequest(String username, String password) {PdaLoginResponse response = new PdaLoginResponse();LoginRequestResult result = new LoginRequestResult();MenuList menuList = new MenuList();List<Menu> menus = menuList.getMenu();//MD5加密開始//String salt = SequenceUtil.getInst().getRandomCode(6);//開始查詢數(shù)據(jù)庫中有沒有用戶名QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<SysUser>();sysUserQueryWrapper.eq("account", username);sysUserQueryWrapper.eq("is_delete", "0");SysUser sysUser = sysUserMapper.selectOne(sysUserQueryWrapper);String encryptPassword="";if (sysUser == null) {result.setRequestResult(false);result.setResultDesc("用戶名不存在");} else {if(sysUser.getSalt()!=null){String salt =sysUser.getSalt();//加密后的密碼encryptPassword = ShiroHelper.SHA1(password, username + salt);//用戶名存在時判斷密碼是否正確sysUserQueryWrapper.eq("password", encryptPassword);SysUser sysUser2 = sysUserMapper.selectOne(sysUserQueryWrapper);if (sysUser2 == null) {result.setRequestResult(false);result.setResultDesc("密碼不正確");} else {Menu menu = new Menu();menu.setMenu("生產領料收貨");menu.setUrl("/ProduceReceiveRequest");menus.add(menu);Menu m = new Menu();m.setMenu("質檢領料收貨");m.setUrl("/QualityReceiveRequest");menus.add(m);Menu m2 = new Menu();m2.setMenu("單件補碼");m2.setUrl("/SolidCodeRequest");menus.add(m);result.setRequestResult(true);result.setResultDesc("登錄成功");}}}response.setRequestResult(result);response.setMenuResult(menuList);return response;}}其他業(yè)務流程要結合具體業(yè)務編寫,注意響應的返回格式。
編寫配置類
在項目目錄下新建config目錄,并新建config類
package com.ws.api.config;import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema;@EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter {@Beanpublic ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {MessageDispatcherServlet servlet = new MessageDispatcherServlet();servlet.setApplicationContext(applicationContext);servlet.setTransformWsdlLocations(true);return new ServletRegistrationBean(servlet, "/ws/*");}@Bean(name = "pda2wms")public DefaultWsdl11Definition pdaWsdl11Definition(XsdSchema pda2wmsSchema) {DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();wsdl11Definition.setPortTypeName("WmsPort");wsdl11Definition.setLocationUri("/");wsdl11Definition.setTargetNamespace("http://test.com/webservice/pda");wsdl11Definition.setSchema(pda2wmsSchema);return wsdl11Definition;}@Beanpublic XsdSchema pda2wmsSchema() {return new SimpleXsdSchema(new ClassPathResource("/xsd/pda2wms.xsd"));} }注:
?wsdl11Definition.setPortTypeName("WmsPort");
接口說明:
設置用于此定義的端口類型名稱。需要。
public void setPortTypeName(String portTypeName)
這里的WmsPort是自動生成的代碼,跟實體類一起生成的。
其他參數(shù)詳細說明參照:
類DefaultWsdl 11定義中英文對比API文檔
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/89394809
啟動項目
編寫項目啟動類并啟動:
package com.ws.api;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.retry.annotation.EnableRetry;@SpringBootApplication @EnableRetry public class ApiApplication {public static void main(String[] args) {SpringApplication.run(ApiApplication.class, args);}}啟動項目后訪問:
http://127.0.0.1:7878/ws/pda2wms.wsdl
本地是127.0.0.1,項目端口號是7878
發(fā)現(xiàn)web service已經成功發(fā)布了。
右鍵點擊另存為
然后就可以使用SoapUI進行測試。測試方法見:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/89356462
總結
以上是生活随笔為你收集整理的SpringBoot整合spring-ws开发webservice接口(全流程详细教程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 类DefaultWsdl 11定义中英文
- 下一篇: gradle idea java ssm