700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 调用WebService 设置超时

调用WebService 设置超时

时间:2023-12-22 06:23:24

相关推荐

调用WebService 设置超时

最近项目上要调用其他系统的WebService(Axis搭建),由于接收数据较大耗时4分钟左右,所以要设置超时时间,而且系统中已有jar包的原因,导致许多方法都不能用,最终用HttpClient。

方法一:使用JaxWsDynamicClientFactory调用WebService

Java代码

publicstaticObjectcall(Stringwsdl,Stringmethod,StringrequestStr){

JaxWsDynamicClientFactoryfactory=JaxWsDynamicClientFactory.newInstance();

Clientclient=factory.createClient(wsdl);

HTTPConduitconduit=(HTTPConduit)client.getConduit();

HTTPClientPolicypolicy=newHTTPClientPolicy();

longtimeout=10*60*1000;//

policy.setConnectionTimeout(timeout);

policy.setReceiveTimeout(timeout);

conduit.setClient(policy);

//动态invoke方法

Object[]os=client.invoke(method,requestStr);

returnos[0];

}

方法二:使用JaxWsProxyFactoryBean调用WebService

原理:使用JaxWsProxyFactoryBean类生成本地的代理类。

首先创建接口,然后通过JaxWsProxyFactoryBean调用。

Java代码

@WebService

publicinterfaceIDataService{

@WebMethod

@WebResult

StringgetData(@WebParamStringrequestData);

}

publicstaticStringcall(Stringwsdl,StringrequestStr){

JaxWsProxyFactoryBeanfactory=newJaxWsProxyFactoryBean();

factory.setServiceClass(IDataService.class);

factory.setAddress(wsdl);

IDataServiceservice=(IDataService)factory.create();

//设置超时时间

org.apache.cxf.endpoint.Clientproxy=ClientProxy.getClient(service);

HTTPConduitconduit=(HTTPConduit)proxy.getConduit();

HTTPClientPolicypolicy=newHTTPClientPolicy();

longtimeout=10*60*1000;//

policy.setConnectionTimeout(timeout);

policy.setReceiveTimeout(timeout);

conduit.setClient(policy);

//发出请求

returnservice.getData(requestStr);

}

方法三:使用wsimport命令构建WebService客户端

首先使用wsimport命令构建客户端,然后用下面的方法调用。

Java代码

publicstaticStringcall(StringrequestData){

//构建的客户端代码

IDataService_Servicefactory=newIDataService_Service();

IDataServiceservice=factory.getDataSharedWebService();

longtimeout=30*60*1000;//30分钟

//设置超时时间

//当前起作用的配置

((BindingProvider)service).getRequestContext().put("javax.xml.ws.client.connectionTimeout",timeout);

((BindingProvider)service).getRequestContext().put("javax.xml.ws.client.receiveTimeout",timeout);

//网上搜到的其他设置超时的方法,当前项目没有起作用

((BindingProvider)service).getRequestContext().put("com.sun.xml.ws.connect.timeout",timeout);

((BindingProvider)service).getRequestContext().put("com.sun.xml.ws.request.timeout",timeout);

((BindingProvider)service).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout",timeout);

((BindingProvider)service).getRequestContext().put("com.sun.xml.internal.ws.request.timeout",timeout);

((BindingProvider)service).getRequestContext().put(".client.defaultConnectTimeout",timeout);

((BindingProvider)service).getRequestContext().put(".client.defaultReadTimeout",timeout);

try{

//调用WebService

returnservice.getData(requestData);

}catch(Exceptione){

log.error(e.getMessage());

}

returnnull;

}

也可以用cxf的wsdl2java命令构建客户端,调用方式一样,但是如何设置超时时间没有试。

方法四:使用HttpClient调用WebService

使用commons-httpclient-3.1,依赖jar包(commons-codec.jar、commons-logging.jar)。

Java代码

publicStringcall(Stringwsdl,StringrequestData){

try{

//requestData可以直接用soapui中请求的数据,注意<![CDATA[]]>的使用

PostMethodpostMethod=newPostMethod(wsdl);

byte[]b=requestData.getBytes("UTF-8");

InputStreamin=newByteArrayInputStream(b,0,b.length);

RequestEntityre=newInputStreamRequestEntity(in,

"text/xml;charset=utf-8");

postMethod.setRequestEntity(re);

//设置headerSOAPAction,不设置的话,会报异常:noSOAPAction

//header,但是SOAPAction的好像任意值都可以

StringsoapAction="XX";

postMethod.setRequestHeader("SOAPAction",soapAction);

HttpClientclient=newHttpClient();

//设置超时(不知道默认是多久,没有设置的时候,也没有报错,设置下保险些)

inttimeout=10*60*1000;

client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);

client.getHttpConnectionManager().getParams().setSoTimeout(timeout);

//

intstatus=client.executeMethod(postMethod);

if(status==200){//成功

InputStreamis=postMethod.getResponseBodyAsStream();

/**

*获取的结果可以参考用soapui调用时的返回值,

*如果约定的返回值是XML,并不会像soapui一样把xml用<![CDATA[]]>包含起来,要注意解析的方法,

*不知道soapui如何处理的,暂时没时间研究。

*/

returngetResponseXML(is);

}else{

log.error("调用Webservice出错;错误代码为:"+status);

}

}catch(Exceptione){

log.error(e.getMessage());

}

returnnull;

}

publicStringgetResponseXML(InputStreamresponse)throwsException{

//根据具体的返回值写的解析

SAXReaderreader=newSAXReader();

Documentdocument=reader.read(response);

Elementroot=document.getRootElement();

List<Element>childElements=root.elements();

for(Elementchild:childElements){

List<Element>datas=child.selectNodes("getOrgInfoResponse/getOrgInfoResponse");

for(Elementnode:datas){

//返回约定的xml

returnnode.getText();

}

}

returnnull;

}

总结下这次遇到的问题:

1.异常:java.lang.NoSuchFieldError: QUALIFIED

jar包冲突,删除jar包(如果可以的话,不能删除就用HttpClient的方式)。由于项目中第三方工具需要XmlSchema-1.3.x.jar,而cxf-2.5作为客户端时需要用到xmlschema-core-2.0.1.jar导致前三种方式都不能用。

2.超时

由于接收数据较大,时间较长,必须设置超时时间。

3.异常:javax.xml.bind.UnmarshalException:unexpected element (uri:"", local:"getDataResponse").Expected elements are <{http://xxx/xx}getOrgInfoResponse>

是namespace的问题,如果用JaxWsProxyFactoryBean的方式,要修改@WebResult中targetNamespace;如果用wsimport命令的方式,需要修改类GetDataResponse中属性getDataResponse的注解中namespace的值。

4.异常:no SOAPAction header

没有设置SOAPAction,设置方式:postMethod.setRequestHeader("SOAPAction", soapAction),soapAction的值是什么好像并不影响结果。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。