Webservice开发指南版权声明本书著作权属于金蝶软件(中国)有限公司所有,在未经本公司许可的情况下,任何单位或个人不得以任何方式对本书的部分或全部内容擅自进行增删,改编,节录,翻译,翻印,改写。金蝶软件(中国)有限公司2015年8月BOSWebService1.1.BOSWebService原理......................................................21.2.发布WebService的约束..................................................31.3.BOSWebService发布......................................................31.3.1.发布流程.........................................................31.3.2.发布WebService..................................................31.3.3.编辑WebService配置文件..........................................41.4.BOSWebService部署......................................................51.4.1.建立web工程.....................................................51.4.2.部署发布文件.....................................................51.4.3.测试是否正确.....................................................61.4.4.Web工程目录及文件截图...........................................61.5.客户端代码.............................................................61.5.1.获取wsdl服务描述文件............................................61.5.2.下载工具.........................................................71.5.3.建立一个新工程...................................................71.5.4.使用java客户端.................................................111.5.5.importVoucher(凭证引入.........................................121.6.BOSwebservice安全性.................................................131.6.1.BOSwebservice安全性概述.......................................131.6.2.不启用安全性....................................................131.6.3.启用安全性......................................................131.6.4.如何安全性启用..................................................141.7.EASLogin登陆webservice说明..........................................141.7.1.EASLogin接口说明...............................................141.7.2.EASLogin异常说明...............................................151.7.3.EASLogin和前面版本的差别.......................................161.8.webservice异常查看...................................................162.WebService客户端开发指南...............................................172.1.前提条件..............................................................172.2.获取WSDL文件.........................................................172.3.生成客户端............................................................182.3.1.生成Java客户端.................................................182.3.2.建立一个新工程..................................................182.3.3.将获取到的WSDL文件拷贝到工程的根目录下:.......................192.3.4.生成客户端......................................................192.4.使用java客户端.......................................................232.5.生成C#客户端.........................................................232.5.1.使用命令行......................................................232.5.2.运行命令生成客户端..............................................242.5.3.使用客户端代码..................................................253.webserviceFAQ..........................................................273.1.在EAS上如何发布一个webservice?.....................................273.2.如何调用一个webservice?.............................................273.3.有哪些工具能够简单的测试webservice?.................................273.4.EASLogin服务登陆如何判断失败.........................................273.5.调用webservice时报com.kingdee.bos.IllegalSessionStateException:Pleaseloginfirst异常?..........................................................273.6.EAS6.0调用webservice时报没有WSConfig.getSrvURL()方法。.............283.7.调用webservice时报java.net.SocketTimeoutException:Readtimedout异常28BOSWebService1.1.BOSWebService原理Webservice主要由SOAP,WSDL,以及UDDI等几块技术组成,以XML格式进行数据的传输。是建立可互操作的分布式应用程序的新平台Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力。使各个异构系统之间实现无缝交互。在本质上是要为应用程序之间提供数据通讯的标准,为企业应用之间动态地提供大颗粒度的服务,并不适合于非常精细的基于会话的方法调用以及复杂的事务(transaction)处理之中。1.2.发布WebService的约束在BOSStudio中发布webService时,只能发布Entity和Façade两种元数据类型成WebService服务端的代码。由于Entity或Façade函数参数和返回值可能包含很多复杂的业务类型,在发布时会生成许多辅助类,一些复杂类型在其他异构系统中生成webService客户端时不能很好的支持,因此建议在建立webService功能时,最好使用Façade,并且提供简单类型的输入和返回参数。1.3.BOSWebService发布1.3.1.发布流程先建立需要发布的Façade,建立粗粒度的业务方法,业务方法尽可能提供简单数据类型的数据参数和返回参数。1.3.2.发布WebService运行BOSStudio,打开“包分类”视图,在其中选中要发布WebService的实体或Façade对象(可同时选中多个),点击鼠标右键,在弹出菜单中选择“发布WebService”,将弹出“发布WebService”向导:选择实体或Façade对象下要发布的方法,手工输入或者点击“浏览”按钮来指定发布生成代码存放的目录,可以同时勾中“追加到配置文件”。这样BOSStudio将会根据选中的对象和要发布的方法生成WebService代码和wsdl描述1.3.3.编辑WebService配置文件在“包分类”视图中,选择要编辑其配置文件的解决方案,点击工具栏上的“编辑WebService配置文件”按钮,将会弹出配置文件编辑向导在其间,可以增加或删除要发布的对象(方法),选择好要发布的对象(方法)后,点击“完成”按钮,即可完成对配置文件的编辑。配置文件位于解决方案的根目录下。1.4.BOSWebService部署1.4.1.部署发布文件发布成功以后,在临时目录里会生成一个wsdd文件和一个目录,例如:D:\webtest\AcctCussentCheckFacade.wsddD:\webtest\com\kingdee\eas\fi\gl\app\webservice\WSAcctCussentCheckFacadeSrvProxy.javaWSAcctCussentCheckFacadeSrvProxy.java文件拷贝到解决方案src目录中,注意包名和路径一致;AcctCussentCheckFacade.wsdd处理方法如下:找到解决方案的runtime\server\deploy\eas.ear目录,用解压缩软件打开web.war,进入WEB-INF目录把AcctCussentCheckFacade.wsdd添加进去;把AcctCussentCheckFacade.wsdd文件里的service节点内容添加到server-config.wsdd文件。操作方法建议:提取server-config.wsdd文件到临时目录,用编辑工具打开,再打开AcctCussentCheckFacade.wsdd,拷贝service节点内容粘贴到server-config.wsdd文件,注意XML格式一致;保存server-config.wsdd文件并拷回到web.war压缩包里。1.4.2.测试是否正确上面的步骤操作完成后,快测已经可以看到新建的WebService。通过浏览器输入服务的地址,访问服务是否正确如输入:http://server-ip:port/ormrpc/servicesBOS快测启动的默认端口为568981.4.3.部署到正式服务器1、在BIM中部署代码和元数据;2、把解决方案下改好的runtime\server\deploy\eas.ear\web.war文件拷贝到EAS服务器的server\deploy\eas.ear目录中,3.将生成的WebService的java代码编译为class,放在EAS服务器的eas\server\deploy\eas.ear\web.war\WEB-INF\class下,或者打成jar包放在eas\server\deploy\eas.ear\web.war\WEB-INF\lib下,把发布的wsdd文件中服务部分拷贝到server-config.wsdd中。4.重启EAS服务器1.4.4.Web工程目录及文件截图1.5.客户端代码1.5.1.获取wsdl服务描述文件WebService已经成功部署到应用服务器上(本文以Apusic为例进行说明),客户端可以通过浏览器访问到已部署的WebService。要构建相关的客户端,就要获取已经部署的WebService的相应的WSDL文件,用鼠标右键点击蓝色的部分“(wsdl)”,选取“目标另存为”菜单,这时将出现选择保存文件位置的对话框,在文件名处将文件的后缀名由xml改为wsdl,将wsdl文件保存至本地。1.5.2.下载工具通过www.eclipse.org下载eclipse(下载j2ee版本)或通过命令行来生成java-Djava.ext.dirs=liborg.apache.axis.wsdl.WSDL2Java其中lib是axis包目录生成客户端代码。1.5.3.建立一个新工程例如建立一个工程名为GenerateWSClient的Java工程:将获取到的WSDL文件拷贝到工程的根目录下用鼠标右键点击要生成客户端的WSDL文件,选取菜单“WebServices”-“GenerateClient”将会弹出生成客户端向导如图,使用默认值,点击“Next>”,进入下一步:依然使用默认值,点击“Next>”,进入下一步:依然使用默认值,点击“Finish”,即可生成相应的客户端工程(是一个Web工程)1.5.4.使用java客户端新生成的工程中有一个JavaSource目录,我们要使用的java代码就位于这个目录,例如上图中的WSLoginProxy.java。以下是一个使用Java客户端的例子:importjava.rmi.RemoteException;importcom.kingdee.WSLoginProxy;//此为发布的代码importcom.client.WSContext;publicclassLoginTest{publicstaticvoidmain(String[]args){try{WSLoginProxyproxy=newWSLoginProxy();/***webservice客户端登陆*userName用户名*password密码*slnNameeas*dcName数据中心,对应的是dataCenter中数据中心id*language语言L2简体*dbType数据库类型0:sqlServer1:db22:oracle*authPattern验证方式默认"BaseDB";其他认证方式KEY可从easAuthPatterns.xml中获取*/WSContextctx=proxy.login("用户","","eas","数据中心id","L2",0);//成功登录后打印sessionIdSystem.out.println(ctx.getSessionId());//调用凭证业务webservice方法importVoucher(凭证引入),请看1.55节}catch(RemoteExceptione){e.printStackTrace();}}}1.5.5.importVoucher(凭证引入1、凭证引入接口,两个接口方法都可用,且用法一致2、凭证webService接口生成客户端,可参考EASLogin方法3、凭证引入参数:importVoucher(wsvoucher[],intisVerify,intisCashflow)传参数第1个:WSWSVoucher[]普通对象数组,见构造EAS凭证字段以及含义说明传参数第2个:isverify0不核销,暂存1核销,暂存2不核销,提交3核销,提交传参数第3个:isImpCashflow是否引入现金流量0不引入1引入4、凭证引入代码调用说明5、返回值String[][]是一个长度为凭证数,宽度是5的字符串数据宽度的定义:外部系统凭证号,凭证字,会计年度,会计期间,处理信息,异常信息,金蝶凭证号1.6.BOSwebservice安全性1.6.1.BOSwebservice安全性概述BOSwebservice安全有两种模式,启用安全性和不启用安全性,默认配置是不启用安全性。1.6.2.不启用安全性在不启用安全性,则访问业务webservice前,先成功调用EASLogin登陆的webservice服务,则系统将记住相关登陆信息,下次调用业务方法是,直接从服务器中获取相关登陆信息。如果多次调用EASLoginwebservice服务,则以最后一次为准。1.6.3.启用安全性在启用安全性后,每次WEBSERVICE访问,必须带上相关的SessionID信息,如下红字部分。系统将根据SOAP头中的SessionID信息,获取相关的上下文信息。
ada894c0-8223-41dc-b816-61eb67dc38bdBF76D8D1id1.6.4.如何安全性启用一、修改eas\Server\eas\server\profiles\server1\config\webservice.propetties文件isRomoteLocate=falseisRomoteUserCheck=true二、修改eas\Server\eas\server\deploy\eas.ear\web.war压缩文件中WEB-INF目录下server-config.wsdd文件.........1.7.EASLogin登陆webservice说明1.7.1.EASLogin接口说明EASLogin中有两个方法方法一、publicWSContextlogin(StringuserName,Stringpassword,StringslnName,StringdcName,Stringlanguage,intdbType)throwsAxisFault方法二、publicWSContextlogin(StringuserName,Stringpassword,StringslnName,StringdcName,Stringlanguage,intdbType,StringauthPattern)throwsAxisFault参数说明:userName:登陆用户名password:登陆密码slnName:解决方案名称(通常为eas)dcName:数据中心numberlanguage:L1(英文)、L2(中文简体)、L3(中文繁体)dbType:数据中心数据库类型0(MSSQLServer)、1(DB2UDB)、2(Oracle)(历史遗留参数)authPattern:EAS的验证方式,在方法一种默然为BaseDB1.7.2.EASLogin异常说明在BOS6.2版本中,EASLogin登陆出错将会返回失败返回报文SOAP协议中soapenv:Fault标签的相关说明供识别故障的代码可供人阅读的有关故障的说明有关是谁引发故障的信息存留涉及Body元素的应用程序专用错误信息1.7.3.EASLogin和前面版本的差别EASLogin在BOS6.2之前,登陆失败后,返回WSContext对象,当WSContext.sessionId是为null或空时,表明登陆失败,失败的具体日志信息在服务器日志中可以查看。BOS6.2修改为当登陆失败,将返回Fault报文(通常客户端引擎代码会用异常方式表示),Fault中将包含具体的错误信息。同时服务器日志中也会打印出错误日志。1.8.webservice异常查看webservice调用错误,将可以在EAS相应的系统日志中查看到相应的信息。如$EASHOME//server/profiles/server1/logs/apusic.log.0有的异常信息也会通过SOAP返回到客户端。可参考返回SOAP的faultstring元素中的错误详细信息。2.WebService客户端开发指南2.1.前提条件WebService已经成功部署到应用服务器上(本文以Apusic为例进行说明),客户端可以通过浏览器访问到已部署的WebService,例如通过以下地址访问到已部署的WebService:http://localhost:6888/easws/services2.2.获取WSDL文件如上图所示,应用服务器已经部署了相关的WebService。要构建相关的客户端,就要获取已经部署的WebService的相应的WSDL文件,用鼠标右键点击蓝色的部分“(wsdl)”,选取“目标另存为”菜单,这时将出现选择保存文件位置的对话框,在文件名处将文件的后缀名由xml改为wsdl,将wsdl文件保存至本地。2.3.生成客户端2.3.1.生成Java客户端下面将以使用Eclipse3.1来生成java客户端为例进行说明。Eclipse3.1可以到www.eclipse.org免费下载。运行后,要为Eclipse配置至少一个相应的应用服务器,例如Tomcat5.5。2.3.2.建立一个新工程例如建立一个工程名为GenerateWSClient的Java工程:2.3.3.将获取到的WSDL文件拷贝到工程的根目录下:2.3.4.生成客户端用鼠标右键点击要生成客户端的WSDL文件,选取菜单“WebServices”-“GenerateClient”将会弹出生成客户端向导:如图,使用默认值,点击“Next>”,进入下一步:依然使用默认值,点击“Next>”,进入下一步:依然使用默认值,点击“Finish”,即可生成相应的客户端工程(是一个Web工程)。2.4.使用java客户端新生成的工程中有一个JavaSource目录,我们要使用的java代码就位于这个目录,例如上图中的WSLoginProxy.java。以下是一个使用Java客户端的例子:importjava.rmi.RemoteException;import_111._19._168._192.easwebservice.services.easlogin.WSLoginProxy;importclient.WSContext;publicclassLoginTest{/***@paramargs*/publicstaticvoidmain(String[]args){try{WSLoginProxyproxy=newWSLoginProxy();WSContextctx=proxy.login("fanfan","","eas","eas50","l2",0);System.out.println(ctx.getSessionId());}catch(RemoteExceptione){e.printStackTrace();}}}所调用的方法中的参数可以从WebService提供者处获得。2.5.生成C#客户端在此,以MicrosoftVisualStudio.Net2003为例说明如何生成C#客户端。用户在正确安装完MicrosoftVisualStudio.Net2003后,需要设置一个环境变量Path=C:\ProgramFiles\MicrosoftVisualStudio.NET2003\SDK\v1.1\Bin,其中C:\ProgramFiles\MicrosoftVisualStudio.NET2003是MicrosoftVisualStudio.NET2003的安装路径。2.5.1.使用命令行运行“cmd”,打开命令行窗口,并进入WSDL文件所在目录(在此为C:\wsdl目录):2.5.2.运行命令生成客户端运行命令wsdlXXX.wsdl(XXX为wsdl文件的文件名),即可生成C#的WebService客户端代码:输入途中命令,按回车键,即可自动生成C#客户端代码:如上图所示,生成了一个文件WSLoginService.cs,这就是我们所需要的客户断代码2.5.3.使用客户端代码运行MicrosoftVisualStudio.NET2003,建立一个工程,将刚刚生成的WSLoginService.cs文件拷贝到工程的根目录,手工为该代码配置合适的命名空间:这时就可以调用该客户端代码了。例如以下代码:usingSystem;namespaceConsoleApplication1{//////SummarydescriptionforClass1.///classClass1{//////Themainentrypointfortheapplication.///[STAThread]staticvoidMain(string[]args){WSLoginServiceproxy=newWSLoginService();WSContextctx=proxy.login("fanfan","","eas","eas50","l2",0);Console.WriteLine(ctx.sessionId);Console.ReadLine();}}}所调用的方法中的参数可以从WebService提供者处获得。3.webserviceFAQ3.1.在EAS上如何发布一个webservice?请看《BOS开发指南_WebService》文档3.2.如何调用一个webservice?请看《BOS开发指南_WebService客户端开发》文档3.3.有哪些工具能够简单的测试webservice?可采用xmlspy软件。在SOAPCreatenewSOAPrequest选择wsdl文件,点击OK选择测试的方法在返回的SOAP报文中,输入相应的参数信息在SOAPSendrequesttoserverxmlspy将访问服务,并列出返回的SOAP报文。3.4.EASLogin服务登陆如何判断失败在BOS6.2之前,EASLogin服务返回WSContext,当WSContext.sessionId是为null或空时,表明登陆失败,失败的具体日志信息在服务器日志中可以查看。在BOS6.2登陆失败,返回SOAP报文则BODY为FAULT标签(即客户端webservice引擎将抛出异常)3.5.调用webservice时报com.kingdee.bos.IllegalSessionStateException:Pleaseloginfirst异常?1、在调用业务的webservice前,需要先调用EASLoginwebservice登陆。2、判断调用EASLoginwebservice是否成功。3.6.EAS6.0调用webservice时报没有WSConfig.getSrvURL()方法。打补丁PT0247173.7.调用webservice时报java.net.SocketTimeoutException:Readtimedout异常在使用webservice客户端调用webservice时,客户端默认会设置一个超时时间,当调用超过该时间后,客户端将会报java.net.SocketTimeoutException:Readtimedout异常。可以通过客户端参数设置改变超时时间如果采用axis1客户端:call=(Call)service.createCall();call.setTimeout(TIMEOUT);如果采用axis2客户端:ServiceClientcall=newServiceClient();call.setOptions(options);call.getOptions().setTimeOutInMilliSeconds(Constants.WSTIMEOUT);4.Webservice返回复杂对象List或者JAVABEAN中包含Listaxis返回对象的基本要求,Axis开发的Webservice中不能直接返回List对象,只能通过数组的方式返回,当然在直接返回List的例子中,服务端代码是返回List,但通过传输后客户端必须以数组的方式进行解读,因此建议直接返回数组方式。4.1.以下为例子源码服务端代码:packagecom.kingdee.model;importjava.util.List;//书本publicclassBookimplementsjava.io.Serializable{/****/privatestaticfinallongserialVersionUID=-8798284029723517521L;//书本名称privateStringname;//书本价格privateDoubleprice;//一本书有多个作者进行编写最好只能用数组方式,请勿用其他方式privateBookAuthor[]bookAuthor;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicDoublegetPrice(){returnprice;}publicvoidsetPrice(Doubleprice){this.price=price;}publicBookAuthor[]getBookAuthor(){returnbookAuthor;}publicvoidsetBookAuthor(BookAuthor[]bookAuthor){this.bookAuthor=bookAuthor;}}Packagecom.kingdee.model;//作者publicclassBookAuthorimplementsjava.io.Serializable{/****/privatestaticfinallongserialVersionUID=-6434694774033892935L;//作者名称privateStringname;//作者简述privateStringdesc;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicStringgetDesc(){returndesc;}publicvoidsetDesc(Stringdesc){this.desc=desc;}}packagecom.kingdee.service;importjava.util.ArrayList;importjava.util.List;importcom.kingdee.model.Book;importcom.kingdee.model.BookAuthor;//书本订购publicclassBookOrder{publicstaticBookbook=newBook();//设置要订购的书名称publicStringsetBookName(Stringname){book.setName(name);BookAuthor[]authorList=newBookAuthor[1];BookAuthorauthor=newBookAuthor();author.setName("bookAuthor");author.setDesc("authorDesc");authorList[0]=author;book.setBookAuthor(authorList);return"success";}//根据名称返回书本,一个书本有多个作者publicBookgetBookByName(Stringname){if(name!=null&&!"".equalsIgnoreCase(name)&&name.equalsIgnoreCase(book.getName()))returnbook;elsereturnnull;}//返回所有(多个)书本publicListgetAllBooks(){ListbookList=newArrayList();bookList.add(book);returnbookList;}}4.2.关键配置<!--定义的webservice名称-->〈!--JAVABEAN内部类型映射转换,也可以自己定义,Boss或者EAS没有自身定义--〉〈!--数组类型映射转换,也可以自己定义,Boss或者EAS没有自身定义--〉〈!--JAVABEAN外部类型映射转换,也可以自己定义,Boss或者EAS没有自身定义--〉将上个内容拷贝到Server-config.xml即便可以,并通过WSDL2JAVA生成客户端代码请勿自己写客户端代码。