`
thewangzl
  • 浏览: 16844 次
  • 性别: Icon_minigender_1
  • 来自: 太和
社区版块
存档分类
最新评论

cxf和HttpClient调用WebService,并设置超时时间

    博客分类:
  • java
阅读更多
    最近项目上要调用其他系统的WebService(Axis搭建),由于接收数据较大耗时4分钟左右,所以要设置超时时间,而且系统中已有jar包的原因,导致许多方法都不能用,最终用HttpClient。
方法一:使用JaxWsDynamicClientFactory调用WebService
	public static Object call(String wsdl,String method,String requestStr){
		JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
		Client client = factory.createClient(wsdl);
		HTTPConduit conduit = (HTTPConduit) client.getConduit();
		HTTPClientPolicy policy = new HTTPClientPolicy();
		long timeout = 10 * 60 * 1000;//
		policy.setConnectionTimeout(timeout);
		policy.setReceiveTimeout(timeout);
		conduit.setClient(policy);
		//动态invoke方法
		Object[] os =client.invoke(method,requestStr);
		return os[0];
		}
 
方法二:使用JaxWsProxyFactoryBean调用WebService
     原理:使用JaxWsProxyFactoryBean类生成本地的代理类。
     首先创建接口,然后通过JaxWsProxyFactoryBean调用。    
@WebService
public interface IDataService {

	@WebMethod
	@WebResult
	String getData(@WebParam String requestData);
}

public static String call(String wsdl, String requestStr) {
	JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
	factory.setServiceClass(IDataService.class);
	factory.setAddress(wsdl);
	IDataService service = (IDataService) factory.create();
	// 设置超时时间
	org.apache.cxf.endpoint.Client proxy = ClientProxy.getClient(service);
	HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
	HTTPClientPolicy policy = new HTTPClientPolicy();
	long timeout = 10 * 60 * 1000;//
	policy.setConnectionTimeout(timeout);
	policy.setReceiveTimeout(timeout);
	conduit.setClient(policy);
	// 发出请求
	return service.getData(requestStr);
}
 
方法三:使用wsimport命令构建WebService客户端
       首先使用wsimport命令构建客户端,然后用下面的方法调用。
	public static String call(String requestData) {
		// 构建的客户端代码
		IDataService_Service factory = new IDataService_Service();
		IDataService service = factory.getDataSharedWebService();
		long timeout = 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("sun.net.client.defaultConnectTimeout", timeout);
		((BindingProvider) service).getRequestContext().put("sun.net.client.defaultReadTimeout", timeout);
		try {
			// 调用WebService
			return service.getData(requestData);
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return null;
	}
     也可以用cxf的wsdl2java命令构建客户端,调用方式一样,但是如何设置超时时间没有试。
 
方法四:使用HttpClient调用WebService
      使用commons-httpclient-3.1,依赖jar包(commons-codec.jar、commons-logging.jar)。
	public String call(String wsdl, String requestData) {
		try {
			// requestData可以直接用soapui中请求的数据,注意<![CDATA[]]>的使用
			PostMethod postMethod = new PostMethod(wsdl);
			byte[] b = requestData.getBytes("UTF-8");
			InputStream in = new ByteArrayInputStream(b, 0, b.length);
			RequestEntity re = new InputStreamRequestEntity(in,
					"text/xml; charset=utf-8");
			postMethod.setRequestEntity(re);
			// 设置header SOAPAction,不设置的话,会报异常:no SOAPAction
			// header,但是SOAPAction的好像任意值都可以
			String soapAction = "XX";
			postMethod.setRequestHeader("SOAPAction", soapAction);
			HttpClient client = new HttpClient();
			// 设置超时(不知道默认是多久,没有设置的时候,也没有报错,设置下保险些)
			int timeout = 10 * 60 * 1000;
			client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
			client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
			//
			int status = client.executeMethod(postMethod);
			if (status == 200) {// 成功
				InputStream is = postMethod.getResponseBodyAsStream();
				/**
				 * 获取的结果可以参考用soapui调用时的返回值,
				 * 如果约定的返回值是XML,并不会像soapui一样把xml用<![CDATA[]]>包含起来,要注意解析的方法,
				 * 不知道soapui如何处理的,暂时没时间研究。
				 */
				return getResponseXML(is);
			} else {
				log.error("调用Webservice出错;错误代码为:" + status);
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return null;
	}

	public String getResponseXML(InputStream response) throws Exception {
		// 根据具体的返回值写的解析
		SAXReader reader = new SAXReader();
		Document document = reader.read(response);
		Element root = document.getRootElement();
		List<Element> childElements = root.elements();
		for (Element child : childElements) {
			List<Element> datas = child.selectNodes("getOrgInfoResponse/getOrgInfoResponse");
			for (Element node : datas) {
				// 返回约定的xml
				return node.getText();
			}
		}
		return null;
	}
  
 总结下这次遇到的问题:
     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的值是什么好像并不影响结果。
分享到:
评论

相关推荐

    使用CXF和camel-cxf调用webservice

    本篇文章将详细介绍如何使用CXF和camel-cxf调用Web服务,以及这两个工具的核心功能和使用场景。 Apache CXF是一个全面的服务开发框架,它支持多种Web服务标准,如SOAP、WS-*协议栈、RESTful服务等。CXF提供了丰富的...

    CXF作为客户端调用webService的demo

    用CXF作为客户端调用webService的demo:本人亲测可用,eclipse工程项目包含完整代码和完整jar包, 只要用eclipse导入项目即可,运行控制台显示success或者false字符串,说明OK。

    camel-cxf调用和发布webservice例子

    用camel-cxf调用webservice和发布一个webservice接口例子,首先启动QueryServiceMain主函数启动webservice接口,然后启动测试类TestWebservice。例子主要是实现java代码实现camel调用webservice接口

    webService(基于cxf)的完整例子

    在这个基于CXF的Web服务完整例子中,我们将深入探讨CXF的核心概念、配置、以及如何创建和调用Web服务。 1. **CXF框架介绍**:CXF,全称为"Code first eXtended Framework",最初由XFire项目发展而来,后与Apache ...

    springboot整合CXF发布webservice和客户端调用

    通过这个项目,开发者不仅可以了解SpringBoot和CXF的基本概念,还能掌握两者如何协同工作,发布和调用Web服务。同时,对于SpringBoot应用的打包、部署和测试也有了一定的认识。这个例子是一个理想的实践项目,对于...

    cxf客户端调用webservice所需jar包

    在Java开发中,Apache CXF是一个广泛使用的开源框架,它提供了创建和消费Web服务的能力。当我们需要在客户端调用Web服务时,CXF扮演着关键角色。本篇将详细讲解如何利用CXF客户端来调用Web服务以及所需的jar包。 ...

    Java cxf开发webservice,分别有客户端和服务端

    2.用cxf开发webservice 3.这个服务端和客户端的小demo 在服务端 对外开放接口服务,然后在客户端 调用服务端的方法, 实现客户端(一个javaweb项目)对服务端(javaweb项目)方法的调用, 实际上就是发送和接收消息...

    cxf超时设置

    "cxf超时设置"这个主题是关于如何在使用CXF框架时,对网络通信的超时时间进行配置,以优化服务的稳定性和性能。 首先,理解超时的概念至关重要。在计算机网络中,超时是指等待某个操作完成的时间限制。当这个时间...

    cxf调用c#的webservice

    - 可以通过调整CXF客户端的配置,例如设置连接超时、重试策略等,来优化性能和稳定性。 总之,使用Apache CXF,Java开发者可以方便地调用C#编写的Web服务,实现跨语言的通信。这个过程涉及到了WSDL解析、Java代理...

    使用CXF发布和调用webservice之HelloWorld入门

    ### 使用CXF发布和调用WebService之HelloWorld入门详解 #### 一、概述 本文将详细介绍如何使用Apache CXF框架来实现一个简单的WebService——HelloWorld示例。此示例不仅适用于初学者理解WebService的基本概念,...

    C#动态调用CXF WEBSERVICE框架的共通类

    C#动态调用CXF WEBSERVICE框架共通类。

    java 调用webservice使用HttpClient和XFire两种方式

    本文将详细介绍如何使用HttpClient和XFire这两种不同的库来调用Web Service,特别是针对短信接口的调用。 首先,让我们了解Web Service的基本概念。Web Service是一种基于互联网的、平台无关的交互方式,它允许不同...

    cxf做的webservice对外提供接口调用

    【标题】:“cxf做的webservice对外提供接口调用” 【描述】中提到的“webservice对外发布接口全部源码拿起来就能用”,这表明这是一个关于使用Apache CXF框架创建和发布的Web服务项目。Apache CXF是一个开源的Java...

    Java webservice cxf客户端调用demo和服务端

    Java WebService CXF客户端调用和服务端的实现是企业级应用程序中常见的通信方式,它基于标准的SOAP(Simple Object Access Protocol)协议,提供了一种在分布式环境中交换信息的方法。CXF是一个开源框架,它简化了...

    CXF和Spring搭建webservice代码

    【CXF和Spring搭建Web服务代码详解】 在Java开发领域,CXF和Spring框架的结合是构建高效、灵活的Web服务的常见选择。CXF是一个开源的SOAP和RESTful Web服务框架,它允许开发者轻松地创建和消费Web服务。而Spring...

    CXF 一个完整的webService(整合客户端和服务端)

    【CXF:构建Web服务的全面指南】 CXF(CXF: XFire Community eXtended)是一个开源的Java框架,用于构建和部署Web服务。...通过理解并掌握CXF的基本概念和操作,你将能够充分利用它的优势,为你的项目带来便利。

    CXF V3.2.4 实现的WebService调用(带安全认证)

    在本文中,我们将深入探讨如何使用Apache CXF V3.2.4实现带有安全认证的Web服务调用。Apache CXF是一个开源框架,它允许开发者创建和消费各种Web服务,包括SOAP和RESTful API。CXF 3.2版本引入了许多增强功能,包括...

    spring集成cxf,server发布webservice,client调用webservice

    使用spring集成cxf,在两个web project里发布及调用webservice server端使用spring+springmvc+mybatis+cxf,client端使用struts2+spring+hibernate+cxf 两个工程均为myeclipse project,包含所有除myeclipse自带以外...

    cxf+spring发布webservice和restservice

    本项目“cxf+spring发布webservice和restservice”专注于利用Apache CXF框架与Spring框架结合,实现这两种服务的发布。Apache CXF是一个开源的、功能丰富的服务栈,它使得开发者能够轻松地构建和部署SOAP和RESTful ...

    spring+CXF实现WebService(http+https)

    Spring框架是Java企业级应用开发的首选,而CXF是一个强大的开源服务框架,支持创建和消费Web服务。本教程将深入探讨如何利用Spring和CXF来实现基于HTTP和HTTPS的Web服务,并且将涉及到HTTPS的证书配置。 1. **...

Global site tag (gtag.js) - Google Analytics