CXF生成的WSDL详解
- 格式:doc
- 大小:36.50 KB
- 文档页数:4
WSDL解析背景前⾯我们介绍过利⽤javassist动态⽣成webservice,这种⽅式可以使得我们系统通过页⾯配置动态发布webservice服务,做到0代码开发发布北向接⼝。
进⼀步思考,我们如何0代码开发调⽤第三⽅webservice服务呢?wsdl解析⾸先必然是理解第三⽅webservice的接⼝描述,也就是解析wsdl⽂件。
wsdl⽂件是webservice服务接⼝描述⽂档,⼀个wsdl⽂件可以包含多个接⼝,⼀个接⼝可以包含多个⽅法。
实际上,wsdl解析是⼗分困难的⼯作,⽹上也没有找到有效的解决办法,最终通过阅读SoapUI源码,找到了完美的解析⽅法。
代码1/**2 * WsdlInfo.java Create on 2013-5-4 下午12:56:143 *4 * 类功能说明: wsdl解析⼊⼝5 *6 * Copyright: Copyright(c) 20137 * Company: COSHAHO8 * @Version 1.09 * @Author 何科序10*/11public class WsdlInfo12 {13private String wsdlName;1415private List<InterfaceInfo> interfaces;1617/**18 * coshaho19 * @param path wsdl地址20 * @throws Exception21*/22public WsdlInfo(String path) throws Exception23 {24 WsdlProject project = new WsdlProject();25 WsdlInterface[] wsdlInterfaces = WsdlImporter.importWsdl( project, path );26this.wsdlName = path;27if(null != wsdlInterfaces)28 {29 List<InterfaceInfo> interfaces = new ArrayList<InterfaceInfo>();30for(WsdlInterface wsdlInterface : wsdlInterfaces)31 {32 InterfaceInfo interfaceInfo = new InterfaceInfo(wsdlInterface);33 interfaces.add(interfaceInfo);34 }35this.interfaces = interfaces;36 }37 }3839public String getWsdlName() {40return wsdlName;41 }4243public void setWsdlName(String wsdlName) {44this.wsdlName = wsdlName;45 }4647public List<InterfaceInfo> getInterfaces() {48return interfaces;49 }5051public void setInterfaces(List<InterfaceInfo> interfaces) {52this.interfaces = interfaces;54 }1/**2 *3 * InterfaceInfo.java Create on 2016年7⽉20⽇下午9:03:214 *5 * 类功能说明: 接⼝信息6 *7 * Copyright: Copyright(c) 20138 * Company: COSHAHO9 * @Version 1.010 * @Author 何科序11*/12public class InterfaceInfo13 {14private String interfaceName;1516private List<OperationInfo> operations;1718private String[] adrress;1920public InterfaceInfo(WsdlInterface wsdlInterface)21 {22this.interfaceName = wsdlInterface.getName();2324this.adrress = wsdlInterface.getEndpoints();2526int operationNum = wsdlInterface.getOperationCount();27 List<OperationInfo> operations = new ArrayList<OperationInfo>();2829for(int i = 0; i < operationNum; i++)30 {31 WsdlOperation operation = ( WsdlOperation )wsdlInterface.getOperationAt( i );32 OperationInfo operationInfo = new OperationInfo(operation);33 operations.add(operationInfo);34 }3536this.operations = operations;37 }3839public String getInterfaceName() {40return interfaceName;41 }4243public void setInterfaceName(String interfaceName) {44this.interfaceName = interfaceName;45 }4647public List<OperationInfo> getOperations() {48return operations;49 }5051public void setOperations(List<OperationInfo> operations) {52this.operations = operations;53 }5455public String[] getAdrress() {56return adrress;57 }5859public void setAdrress(String[] adrress) {60this.adrress = adrress;61 }62 }1/**2 *3 * OperationInfo.java Create on 2016年7⽉20⽇下午9:03:424 *5 * 类功能说明: ⽅法信息6 *7 * Copyright: Copyright(c) 20138 * Company: COSHAHO9 * @Version 1.010 * @Author 何科序11*/12public class OperationInfo13 {14private String operationName;1516private String requestXml;1718private String responseXml;20public OperationInfo(WsdlOperation operation)21 {22 operationName = operation.getName();23 requestXml = operation.createRequest( true );24 responseXml = operation.createResponse(true);25 }2627public String getOperationName() {28return operationName;29 }3031public void setOperationName(String operationName) {32this.operationName = operationName;33 }3435public String getRequestXml() {36return requestXml;37 }3839public void setRequestXml(String requestXml) {40this.requestXml = requestXml;41 }4243public String getResponseXml() {44return responseXml;45 }4647public void setResponseXml(String responseXml) {48this.responseXml = responseXml;49 }50 }测试代码1package com.coshaho.integration;23import com.coshaho.integration.wsdl.InterfaceInfo;4import com.coshaho.integration.wsdl.OperationInfo;5import com.coshaho.integration.wsdl.WsdlInfo;67/**8 *9 * WSDLParseTest.java Create on 2016年7⽉20⽇下午9:24:3610 *11 * 类功能说明: WSDL解析测试12 *13 * Copyright: Copyright(c) 201314 * Company: COSHAHO15 * @Version 1.016 * @Author 何科序17*/18public class WSDLParseTest19 {20public static void main(String[] args) throws Exception21 {22 String url = "/WebServices/ChinaOpenFundWS.asmx?wsdl";23 WsdlInfo wsdlInfo = new WsdlInfo(url);24 System.out.println("WSDL URL is " + wsdlInfo.getWsdlName());2526for(InterfaceInfo interfaceInfo : wsdlInfo.getInterfaces())27 {28 System.out.println("Interface name is " + interfaceInfo.getInterfaceName());29for(String ads : interfaceInfo.getAdrress())30 {31 System.out.println("Interface address is " + ads);32 }33for(OperationInfo operation : interfaceInfo.getOperations())34 {35 System.out.println("operation name is " + operation.getOperationName());36 System.out.println("operation request is ");37 System.out.println("operation request is " + operation.getRequestXml());38 System.out.println("operation response is ");39 System.out.println(operation.getResponseXml());40 }41 }42 }43 }测试结果1 WSDL URL is /WebServices/ChinaOpenFundWS.asmx?wsdl2 Interface name is ChinaOpenFundWSSoap123 Interface address is /WebServices/ChinaOpenFundWS.asmx4 operation name is getFundCodeNameDataSet5 operation request is6 operation request is <soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/">7<soap:Header/>8<soap:Body>9<web:getFundCodeNameDataSet/>10</soap:Body>11</soap:Envelope>12 operation response is13<soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/" xmlns:xs="/2001/XMLSchema"> 14<soap:Header/>15<soap:Body>16<web:getFundCodeNameDataSetResponse>17<!--Optional:-->18<web:getFundCodeNameDataSetResult>19<xs:schema>20<!--Ignoring type [{/2001/XMLSchema}schema]-->21</xs:schema>22<!--You may enter ANY elements at this point-->23</web:getFundCodeNameDataSetResult>24</web:getFundCodeNameDataSetResponse>25</soap:Body>26</soap:Envelope>27 operation name is getFundCodeNameString28 operation request is29 operation request is <soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/">30<soap:Header/>31<soap:Body>32<web:getFundCodeNameString/>33</soap:Body>34</soap:Envelope>35 operation response is36<soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/">37<soap:Header/>38<soap:Body>39<web:getFundCodeNameStringResponse>40<!--Optional:-->41<web:getFundCodeNameStringResult>42<!--Zero or more repetitions:-->43<web:string>?</web:string>44</web:getFundCodeNameStringResult>45</web:getFundCodeNameStringResponse>46</soap:Body>47</soap:Envelope>48 operation name is getOpenFundDataSet49 operation request is50 operation request is <soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/">51<soap:Header/>52<soap:Body>53<web:getOpenFundDataSet>54<!--Optional:-->55<web:userID>?</web:userID>56</web:getOpenFundDataSet>57</soap:Body>58</soap:Envelope>59 operation response is60<soap:Envelope xmlns:soap="/2003/05/soap-envelope" xmlns:web="/" xmlns:xs="/2001/XMLSchema"> 61<soap:Header/>62<soap:Body>63<web:getOpenFundDataSetResponse>64<!--Optional:-->65<web:getOpenFundDataSetResult>66<xs:schema>67<!--Ignoring type [{/2001/XMLSchema}schema]-->68</xs:schema>69<!--You may enter ANY elements at this point-->70</web:getOpenFundDataSetResult>71</web:getOpenFundDataSetResponse>72</soap:Body>73</soap:Envelope>。
利⽤wsdl2java⼯具⽣成webservice的客户端代码 1、JDK环境 2、下载apache-cxf发布包: ⽬前最新版本为3.2.6, 解压后如下: 解压发布包,设置CXF_HOME,并添加%CXF_HOME %/bin到path环境变量。
3、CMD命令⾏输⼊wsdl2java -help,有正常提⽰说明环境已经正确配置。
4、命令使⽤ 此命令主要是⽣成webservice的客户端代码,服务端可以是⾃⾏开发的服务,也可以是需要对接的服务接⼝,最简单的命令如下: wsdl2java wsdlurl 其中wsdlurl为服务发布的访问地址,未写参数默认⽣成的是客户端的代码,其中⽤得最多的是-encoding 参数,是指定java代码的编码格式,例如: wsdl2java -encoding wsdlurl 其他详细的参数及说明可以⽤wsdl2java -help或wsdl2java -h获取,根据实际的需求设置相应的参数即可。
5、简单案例 常⽤接⼝:IP地址来源搜索 WEB 服务 1、⽣成客户端代码 WSDL地址: http://12.21.26.11/spesvc/Opp/Service.asmx?wsdl 使⽤wsdl2java⼯具将客户端代码直接⽣成在eclipse的⼯程⾥,eclipse⼯程地址为:E:\workspace\webservice,命令如下: wsdl2java -encoding utf-8 -d E:/webservice/src http://12.23.24.24/spesvc/Opp/OppService.asmx?wsdl -encoding表⽰⽣成的Java⽂件编码格式为utf8,-d表⽰代码⽣成路径为E:/workspace/webservice/src。
执⾏完毕,没有报任何错误,说明执⾏成功 ⽣成代码⽂件如下: 6、客户端代码调⽤服务 写⼀个⼩demo,调⽤发布的IP查询服务public class test_client {public static void main(String[] args){OttService service2 = new OttService();OttServiceSoap serviceSoap = service2.getOttServiceSoap();String rest = serviceSoap.getPlayListGuidWithDate("2018-09-01"); System.out.println(rest);}} 运⾏结果。
/docs/index.html/注意,在非java-project中,例如在web-project中可能出现(activation.jar和mail.jar)与工程中的j2ee.jar以及myeclipse中D:\MyEclipse 5.5.1 GA\myeclipse\eclipse\plugins\com.genuitec.eclipse.j2eedt.core_5.5.1\data\libraryset\EE_5的javaee.jar里面的同名包发生冲突,建议把j2ee.jar和javaee.jar中的同名包删除,或者直接使用J2ee.jar把eclipse自带的javaee.jar从工程中去除并加入相应的包1.WSDL2JA V A生成客户端代码2.JAXB3.JAX-WS4.WS-Addressing5.WS-Policy6.WS-Security7.webservice 注释8.拦截器WSDL2JA V A生成客户端代码CXF支持代码生成1)Java to WSDL 、2)WSDL to Java 、3)XSD to WSDL 、4)WSDL to XML5)WSDL to SOAP 、6)WSDL to service如下:D:\apache-cxf-2.2.5\bin>wsdl2java -d d:/cxf-client -p example1.client http://127.0.0.1:8080/ws/HelloWorld?wsdlJAXB/group/10141/topic/12028CXF默认的数据绑定使用的JAXB,XFIRE使用Aegis替代数据绑定就是把java对象转化为xml和把xml文件转化为java对象不管使用任何的XML解析代码库(dom4j等),对于xml只是一个解析工作而已,不能马上绑定到java 对象。
对于对象,每次都需要set 或者get相应的属性,当然也可以使用map 来保存xml配置。
使用Spring+CXF开发WebServiceApache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services各种类型的Annotation。
@WebService和@WebMethod是WSDL映射Annatotion。
这些Annotation将描述Web Service的WSDL文档元素和Java源代码联系在一起。
@SOAPBinding是一个绑定的annotation用来说明网络协议和格式。
1、@WebService annotation的元素name,serviceName和targetNamespace成员用来描述wsdl:portType,wsdl:service,和targetNameSpace生成WebService中的WSDL文件。
2、@SOAPBinding是一个用来描述SOAP格式和RPC的协议的绑定Annotation。
3、@WebMethod Annotation的operationName成员描述了wsdl:operation,而且它的操作描述了WSDL文档中的SOAPAction头部。
这是客户端必须要放入到SQAPHeader中的数值,SOAP 1.1中的一种约束。
4、@WebParam Annotation的partName成员描述了WSDL文档中的wsdl:part。
5、@WebResult Annotation的partName成员描述了wsdl:part用来返回WSDL文档的值。
例如下面使用annotation定义了一个webservice:import java.util.List;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import er;@WebService(targetNamespace = "/client") public interface UserService {@WebMethod(operationName="Insert")public void insert( @WebParam(name = "userId") String userid,@WebParam(name = "userName") String username,@WebParam(name = "userEmail") String useremail,@WebParam(name = "userAge") int userage);@WebMethod(operationName="GetUserById")@WebResult(name = "result")public User getUserById(@WebParam(name="userid") String userid);@WebMethod(operationName="GetAllUsers")@WebResult(name = "result")public List getAllUsers();}其实现类如下所示:import java.util.List;import javax.jws.WebService;import erDao;import er;import erService;@WebService(endpointInterface="erService")public class UserServiceImpl implements UserService {private UserDao userDao;public List getAllUsers() {return userDao.findAllUser();}public User getUserById(String userid) {return userDao.findUserById(userid);}public void insert(String userid, String username, String useremail, int userage) {User user=new User();user.setUserage(userage);user.setUseremail(useremail);user.setUserid(userid);user.setUsername(username);userDao.insert(user);System.out.println("insert successfully!");}public void setUserDao(UserDao userDao) {erDao = userDao;}}注意:实现类中的@WebService,其中的endpointInterface成员指定了该类实现的接口在Spring的配置文件中,需要对其进行配置:首先在ApplicationContext.xml(Spring的配置文件)中引入CXF的XML Scheam 配置文件),如下:<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:jaxws="/jaxws"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /jaxws/schemas/jaxws.xsd"><!—还需要引入以下3个关于CXF的资源文件,这三个文件在cxf.jar中--><import resource="classpath:META-INF/cxf/cxf.xml" /><import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />……………………………………………………</bean>其次就是在Spring的配置文件中配置webservice,如下所示:<jaxws:endpoint id="userManager" address="/UserManager"implementorClass="erService"><jaxws:implementor><bean id="userServiceImpl"class="erServiceImpl"><property name="userDao"><ref bean="userDao" /></property></bean></jaxws:implementor></jaxws:endpoint>注意:①、address 为webservice发布的地址②、implementorClass 为该webservice实现的接口③、<jaxws:implementor></jaxws:implementor>之间定义的是implementorClass指定接口的实现类另外,在Spring的配置文件中配置完成后,需要修改web.xml文件<servlet><servlet-name>CXFServlet</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>CXFServlet</servlet-name><url-pattern>/services/*</url-pattern></servlet-mapping>注意<url-pattern>/ services /*</url-pattern>配置,CXFServlet会拦截此类url,进行处理。
WebService使⽤介绍(三)jax-ws开发深⼊JAX-WS注解注解说明WebService的注解都位于javax.jws包下:@WebService-定义服务,在public class上边targetNamespace:指定命名空间name:portType的名称portName:port的名称serviceName:服务名称@WebMethod-定义⽅法,在公开⽅法上边operationName:⽅法名exclude:设置为true表⽰此⽅法不是webservice⽅法,反之则表⽰webservice⽅法@WebResult-定义返回值,在⽅法返回值前边name:返回结果值的名称@WebParam-定义参数,在⽅法参数前边name:指定参数的名称作⽤:通过注解,可以更加形像的描述Web服务。
对⾃动⽣成的wsdl⽂档进⾏修改,为使⽤者提供⼀个更加清晰的wsdl⽂档。
当修改了WebService注解之后,会影响客户端⽣成的代码。
调⽤的⽅法名和参数名也发⽣了变化注解⽰例:/*** 天⽓查询服务接⼝实现类* @author SMN* @version V1.0*/@WebService(targetNamespace="http:// ",serviceName="weatherService",portName="weatherServicePort",name="weatherServiceInterface")public class WeatherInterfaceImpl implements WeatherInterface {@WebMethod(operationName="queryWeather")public @WebResult(name="weatherResult")String queryWeather(@WebParam(name="cityName")String cityName) {System.out.println("from client.."+cityName);String result = "晴朗";System.out.println("to client..."+result);return result;}public static void main(String[] args) {//发送webservice服务Endpoint.publish("http://192.168.1.100:1234/weather", new WeatherInterfaceImpl());}}使⽤注解注意@WebMethod对所有⾮静态的公共⽅法对外暴露为服务.对于静态⽅法或⾮public⽅法是不可以使⽤@WebMethod注解的.对public⽅法可以使⽤@WebMethod(exclude=true)定义为⾮对外暴露的服务。
WebService接⼝的⼏种调⽤⽅式--wsdl⽂件类型⾸先⽐如查询到的⼀个wsdl⽂件内容如下:<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" xmlns:apachesoap="/xml-soap" xmlns:impl="http://198.168.0.88:6888/ormrpc/services/EASLogin" xmlns:intf="http://198.168.0.88:68 <!--WSDL created by Apache Axis version: 1.4Built on Apr 22, 2006 (06:55:48 PDT)--><wsdl:types><schema targetNamespace="urn:client" xmlns="/2001/XMLSchema"><import namespace="/soap/encoding/"/><complexType name="WSContext"><sequence><element name="dbType" type="xsd:int"/><element name="dcName" nillable="true" type="xsd:string"/><element name="password" nillable="true" type="xsd:string"/><element name="sessionId" nillable="true" type="xsd:string"/><element name="slnName" nillable="true" type="xsd:string"/><element name="userName" nillable="true" type="xsd:string"/></sequence></complexType></schema></wsdl:types><wsdl:message name="logoutResponse"><wsdl:part name="logoutReturn" type="xsd:boolean"></wsdl:part></wsdl:message><wsdl:message name="loginResponse"><wsdl:part name="loginReturn" type="tns1:WSContext"></wsdl:part></wsdl:message><wsdl:message name="loginRequest"><wsdl:part name="userName" type="xsd:string"></wsdl:part><wsdl:part name="password" type="xsd:string"></wsdl:part><wsdl:part name="slnName" type="xsd:string"></wsdl:part><wsdl:part name="dcName" type="xsd:string"></wsdl:part><wsdl:part name="language" type="xsd:string"></wsdl:part><wsdl:part name="dbType" type="xsd:int"></wsdl:part><wsdl:part name="authPattern" type="xsd:string"></wsdl:part></wsdl:message><wsdl:message name="loginResponse1"><wsdl:part name="loginReturn" type="tns1:WSContext"></wsdl:part></wsdl:message><wsdl:message name="logoutRequest"><wsdl:part name="userName" type="xsd:string"></wsdl:part><wsdl:part name="slnName" type="xsd:string"></wsdl:part><wsdl:part name="dcName" type="xsd:string"></wsdl:part><wsdl:part name="language" type="xsd:string"></wsdl:part></wsdl:message><wsdl:message name="loginResponse2"><wsdl:part name="loginReturn" type="tns1:WSContext"></wsdl:part></wsdl:message><wsdl:message name="loginRequest1"><wsdl:part name="userName" type="xsd:string"></wsdl:part><wsdl:part name="password" type="xsd:string"></wsdl:part><wsdl:part name="slnName" type="xsd:string"></wsdl:part><wsdl:part name="dcName" type="xsd:string"></wsdl:part><wsdl:part name="language" type="xsd:string"></wsdl:part><wsdl:part name="dbType" type="xsd:int"></wsdl:part></wsdl:message><wsdl:message name="loginByLtpaTokenRequest"><wsdl:part name="userName" type="xsd:string"></wsdl:part><wsdl:part name="ltpaToken" type="xsd:string"></wsdl:part><wsdl:part name="slnName" type="xsd:string"></wsdl:part><wsdl:part name="dcName" type="xsd:string"></wsdl:part><wsdl:part name="language" type="xsd:string"></wsdl:part><wsdl:part name="dbType" type="xsd:int"></wsdl:part></wsdl:message><wsdl:message name="loginRequest2"><wsdl:part name="userName" type="xsd:string"></wsdl:part><wsdl:part name="password" type="xsd:string"></wsdl:part><wsdl:part name="slnName" type="xsd:string"></wsdl:part><wsdl:part name="dcName" type="xsd:string"></wsdl:part><wsdl:part name="language" type="xsd:string"></wsdl:part><wsdl:part name="dbType" type="xsd:int"></wsdl:part><wsdl:part name="authPattern" type="xsd:string"></wsdl:part><wsdl:part name="isEncodePwd" type="xsd:int"></wsdl:part></wsdl:message><wsdl:message name="loginByLtpaTokenResponse"><wsdl:part name="loginByLtpaTokenReturn" type="tns1:WSContext"></wsdl:part></wsdl:message><wsdl:portType name="EASLoginProxy"><wsdl:operation name="logout" parameterOrder="userName slnName dcName language"><wsdl:input message="impl:logoutRequest" name="logoutRequest"></wsdl:input><wsdl:output message="impl:logoutResponse" name="logoutResponse"></wsdl:output></wsdl:operation><wsdl:operation name="login" parameterOrder="userName password slnName dcName language dbType authPattern"> <wsdl:input message="impl:loginRequest" name="loginRequest"></wsdl:input><wsdl:output message="impl:loginResponse" name="loginResponse"></wsdl:output></wsdl:operation><wsdl:operation name="login" parameterOrder="userName password slnName dcName language dbType"><wsdl:input message="impl:loginRequest1" name="loginRequest1"></wsdl:input><wsdl:output message="impl:loginResponse1" name="loginResponse1"></wsdl:output></wsdl:operation><wsdl:operation name="login" parameterOrder="userName password slnName dcName language dbType authPattern isEncodePwd"><wsdl:input message="impl:loginRequest2" name="loginRequest2"></wsdl:input><wsdl:output message="impl:loginResponse2" name="loginResponse2"></wsdl:output></wsdl:operation><wsdl:operation name="loginByLtpaToken" parameterOrder="userName ltpaToken slnName dcName language dbType"><wsdl:input message="impl:loginByLtpaTokenRequest" name="loginByLtpaTokenRequest"></wsdl:input><wsdl:output message="impl:loginByLtpaTokenResponse" name="loginByLtpaTokenResponse"></wsdl:output></wsdl:operation></wsdl:portType><wsdl:binding name="EASLoginSoapBinding" type="impl:EASLoginProxy"><wsdlsoap:binding style="rpc" transport="/soap/http"/><wsdl:operation name="logout"><wsdlsoap:operation soapAction=""/><wsdl:input name="logoutRequest"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="" use="encoded"/> </wsdl:input><wsdl:output name="logoutResponse"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" use="encoded"/> </wsdl:output></wsdl:operation><wsdl:operation name="login"><wsdlsoap:operation soapAction=""/><wsdl:input name="loginRequest"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="" use="encoded"/> </wsdl:input><wsdl:output name="loginResponse"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" use="encoded"/> </wsdl:output></wsdl:operation><wsdl:operation name="login"><wsdlsoap:operation soapAction=""/><wsdl:input name="loginRequest1"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="" use="encoded"/> </wsdl:input><wsdl:output name="loginResponse1"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" use="encoded"/> </wsdl:output></wsdl:operation><wsdl:operation name="login"><wsdlsoap:operation soapAction=""/><wsdl:input name="loginRequest2"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="" use="encoded"/> </wsdl:input><wsdl:output name="loginResponse2"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" use="encoded"/> </wsdl:output></wsdl:operation><wsdl:operation name="loginByLtpaToken"><wsdlsoap:operation soapAction=""/><wsdl:input name="loginByLtpaTokenRequest"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="" use="encoded"/> </wsdl:input><wsdl:output name="loginByLtpaTokenResponse"><wsdlsoap:body encodingStyle="/soap/encoding/" namespace="http://198.168.0.88:6888/ormrpc/services/EASLogin" use="encoded"/> </wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="EASLoginProxyService"><wsdl:port binding="impl:EASLoginSoapBinding" name="EASLogin"><wsdlsoap:address location="http://198.168.0.88:6888/ormrpc/services/EASLogin"/></wsdl:port></wsdl:service></wsdl:definitions>⼀般有⼏种⽅式调⽤此接⼝:⽅式⼀:通过wsdl⽂件或者链接使⽤相关IDE软件⽣成Java⽂件这种⽅式⽐较累赘,不做推荐,使⽤IDE软甲即可完成⽅式⼆:使⽤apache的动态代理⽅式实现话不多说,直接上代码:import .URL;import space.QName;import org.apache.axis.client.Call;import org.apache.axis.client.Service;public class UsingDII {public static void main(String[] args) {try {int a = 100, b=60; // 对应的targetNamespaceString endPoint = "http://198.168.0.88:6888/ormrpc/services/EASLogin";Service service = new Service();Call call = (Call)service.createCall();call.setOperationName(new QName(endPoint,"EASLogin"));call.setTargetEndpointAddress(new URL(endPoint)); // a,b 调⽤此⽅法的参数String result = (String)call.invoke(new Object[]{new Integer(a),new Integer(b)});System.out.println("result is :"+result);} catch (Exception e) {e.printStackTrace();}}}⽅式三:使⽤Dynamic Proxy动态代理import .URL;import javax.xml.*;public class UsingDP {public static void main(String[] args) {try {int a = 100, b=60;String wsdlUrl = "http://198.168.0.88:6888/ormrpc/services/EASLogin?wsdl";String nameSpaceUri = "http://198.168.0.88:6888/ormrpc/services/EASLogin";String serviceName = "EASLoginProxyService";String portName = "EASLogin";ServiceFactory serviceFactory = ServiceFactory.newInstance();Service service = serviceFactory.createService(new URL(wsdlUrl),new QName(nameSpaceUri,serviceName)); // 返回值是⾃⼰封装的类AddFunctionServiceIntf adsIntf = (AddFunctionServiceIntf)service.getPort(new QName(nameSpaceUri,portName),AddFunctionServiceIntf.class); System.out.println("result is :"+adsIntf.addInt(a, b));} catch (Exception e) {e.printStackTrace();}}}⽅式四:使⽤httpclient⽅式参考:直接上代码:import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import mons.httpclient.HttpClient;import mons.httpclient.methods.InputStreamRequestEntity;import mons.httpclient.methods.PostMethod;import mons.httpclient.methods.RequestEntity;import org.apache.log4j.Logger;import org.dom4j.Document;import org.dom4j.io.SAXReader;// 这⾥引得依赖包的话需要⾃⼰找了下⾯地址可以找到//https:///public static InputStream postXmlRequestInputStream(String requestUrl, String xmlData) throws IOException{PostMethod postMethod = new PostMethod(requestUrl);byte[] b = xmlData.getBytes("utf-8");InputStream is = new ByteArrayInputStream(b, 0, b.length);RequestEntity re = new InputStreamRequestEntity(is, b.length, "text/xml;charset=utf-8");postMethod.setRequestEntity(re);HttpClient httpClient = new HttpClient();httpClient.getParams().setAuthenticationPreemptive(true);httpClient.getHostConfiguration().setProxy(CommonPptsUtil.get("PROXY_HOST"), Integer.valueOf(CommonPptsUtil.get("PROXY_PORT")));int statusCode = httpClient.executeMethod(postMethod);logger.debug("responseCode:"+statusCode);if (statusCode != 200) {return null;}return postMethod.getResponseBodyAsStream();}public static void main(String[] args) {String reqJsonStr = "{\"workId\":\"20171018161622\",\"status\":\"201\",\"startTime\":\"2017-10-18 16:16:22\"}";String xmlData = "<soapenv:Envelope xmlns:soapenv=\"/soap/envelope/\" xmlns:ser=\"/\"><soapenv:Header/><soapenv:Body><ser:statusWriteBack><jsonString>" + "{\"workId\":\"314\",\"orderId\":\"5207675\",\"longitude\":\"104.068310\",\"latitude\":\"30.539503\",\"sendTime\":\"2019-08-13 08:38:45\",\"servicePerName\":\"于xx\",\"servicePerPhone\":\"184xxxx7680\"}"+ "</jsonString></ser:statusWriteBack></soapenv:Body></soapenv:Envelope>";String url = "http://xx.xxx.246.88:7103/avs/services/CCService?wsdl";SAXReader reader = new SAXReader();String result = "";try {InputStream in = postXmlRequestInputStream(url,xmlData);if(in!=null){Document doc = reader.read(in);result = doc.getRootElement().element("Body").element("statusWriteBackResponse").element("return").getText();logger.debug("result:"+result);}} catch (Exception e) {logger.error("error:",e);e.printStackTrace();}}}CommonPptsUtil://就是获取配置⽂件⾥的代理信息import mons.configuration.ConfigurationException;import mons.configuration.PropertiesConfiguration;import mons.configuration.reloading.FileChangedReloadingStrategy;import org.apache.log4j.Logger;/*** 通⽤属性⽂件⼯具类** @author y.c**/public class CommonPptsUtil {private static final Logger logger = Logger.getLogger(CommonPptsUtil.class);private static final String CONFIG_FILE = "common.properties";private static PropertiesConfiguration ppts;static {try {ppts = new PropertiesConfiguration(CONFIG_FILE);ppts.setReloadingStrategy(new FileChangedReloadingStrategy());} catch (ConfigurationException e) {logger.error("⽂件【common.properties】加载失败!");ppts = null;}}/*** 获取属性值** @param key* @return属性值*/public static String get(String key) {if (ppts == null) {return null;}return ppts.getString(key);}}⽅式五:使⽤CXF动态调⽤webservice接⼝代码如下:参考:package cxfClient;import org.apache.cxf.endpoint.Endpoint;import space.QName;import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;import org.apache.cxf.service.model.BindingInfo;import org.apache.cxf.service.model.BindingOperationInfo;public class CxfClient {public static void main(String[] args) throws Exception {String url = "http://localhost:9091/Service/SayHello?wsdl";String method = "say";Object[] parameters = new Object[]{"我是参数"};System.out.println(invokeRemoteMethod(url, method, parameters)[0]);}public static Object[] invokeRemoteMethod(String url, String operation, Object[] parameters){JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();if (!url.endsWith("wsdl")) {url += "?wsdl";}org.apache.cxf.endpoint.Client client = dcf.createClient(url);//处理webService接⼝和实现类namespace不同的情况,CXF动态客户端在处理此问题时,会报No operation was found with the name的异常Endpoint endpoint = client.getEndpoint();QName opName = new QName(endpoint.getService().getName().getNamespaceURI(),operation);BindingInfo bindingInfo= endpoint.getEndpointInfo().getBinding();if(bindingInfo.getOperation(opName) == null){for(BindingOperationInfo operationInfo : bindingInfo.getOperations()){if(operation.equals(operationInfo.getName().getLocalPart())){opName = operationInfo.getName();break;}}}Object[] res = null;try {res = client.invoke(opName, parameters); } catch (Exception e) {e.printStackTrace();}return res;}}。
wsdl文件用法(一)WSDL文件简介WSDL(Web Services Description Language)是一种用于描述WebService的XML格式文件。
它定义了WebService的接口、参数、操作和数据格式等信息,可以帮助开发者了解和使用特定的WebService。
WSDL文件的用途•WebService接口定义:WSDL文件提供了详细的WebService接口定义,包括可用操作、输入参数和输出结果等信息。
开发者可以通过查看WSDL文件来理解和调用特定WebService。
•自动生成客户端代码:WSDL文件可以用于生成客户端代码,使开发者可以更方便地调用WebService。
许多开发框架和工具(如SOAPUI、Apache CXF)都支持根据WSDL生成客户端代码。
•WebService测试:WSDL文件可以作为测试的依据,测试人员可以根据WSDL文件中定义的接口和操作,编写相关的测试用例和断言条件。
•WebService文档化和交流:WSDL文件可以作为文档,用于记录WebService的接口和数据格式等定义,便于开发者和团队之间的交流和理解。
WSDL文件的结构•Definitions:WSDL文件的根元素,包含了整个文件的定义和命名空间等信息。
•Types:定义了WebService中使用的数据类型,可以是基本类型、复合类型或自定义类型。
•Message:定义了WebService的消息,包括消息的名称和消息中使用的数据类型。
•PortType:定义了WebService的接口,包括可用的操作和操作的输入输出等信息。
•Binding:将WebService的接口定义与具体的通信协议绑定在一起,如SOAP、HTTP等。
•Service:定义了WebService的服务地址和服务的实现名称等信息。
WSDL文件的编写和使用1.创建WSDL文件:可以使用文本编辑器创建一个扩展名为.wsdl的文件。
<?xml version='1.0' encoding='UTF-8'?>
<!--这里的name是发布的service类名 + "Service", targetNamespace 是取决于发布类所在的包 -->
<wsdl:definitions name="HelloWorldImplService" targetNamespace="http://test/">
<!--types 的作用是定义输入输出参数都是什么样子的(类型) -->
<wsdl:types >
<xs:schema elementFormDefault="unqualified" targetNamespace="http://test/" version="1.0"> <!--输入参数名字为‘sayHello’,类型是复杂类型‘sayHello’,在下面定义 -->
<xs:element name="sayHello" type="tns:sayHello"/>
<!--输出参数名字为‘sayHelloResponse’,类型是复杂类型sayHelloResponse, 在下面定义-->
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<!--输入参数类型的具体定义:包含一个element,名字为arg0,类型为string-->
<xs:complexType name="sayHello">
<!-- 这里的name 是自动生成的。
当然,也可以在代码中指定名字。
public @WebResult(name="sayHelloResult") String sayHello(@WebParam(name="name") String str) -->
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
.
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<!--这个message代表输入信息。
这个输入信息的类型是sayHello,在<types>中定义过 -->
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters"></wsdl:part>
</wsdl:message>
<!--这个message代表输出信息。
这个输出信息的类型是sayHelloResponse,在<types>中定义过 --> <wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<!--portType 就是我们定义的接口。
一个接口对应一个port -->
<wsdl:portType name="HelloWorld">
<!--这里的一个operation就是接口中的一个方法 -->
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello">
</wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
.
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<!--把接口进行 soap 绑定-->
<wsdl:binding name="HelloWorldImplServiceSoapBinding" type="tns:HelloWorld"> <!-- 这里指明绑定的协议为 http,style为document-->
<soap:binding style="document" transport="/soap/http"/> <!-- 具体方法的绑定类型定义-->
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHello">
<!--literal文本 -->
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!--把n个接口放到一起,总称为一个service -->
<wsdl:service name="HelloWorldImplService">
.
<!--这里一个port就是一个接口。
对应的绑定刚刚定义过 -->
<wsdl:port binding="tns:HelloWorldImplServiceSoapBinding" name="HelloWorldImplPort"> <!--这个接口的地址 -->
<soap:address location="http://localhost:8080/HelloWorld" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
.。