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

    最近项目上要调用其他系统的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的值是什么好像并不影响结果。

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

深刻理解IdentityHashMap - 2016-09-23 14:09:05

新建POJO package test;public class Cat {private String name;private Integer age;public Cat(String name, Integer age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public In

成为java高手的八大条件 - 2016-09-23 14:09:05

成为java高手的八大条件 世界上并没有成为高手的捷径,但一些基本原则是可以遵循的。兄弟连JavaEE培训导师,告诉你学习java有这样的素质才能成为高手! 1、扎实的基础 数据结构、离散数学、编译原理,这些是所有计算机科学的基础,如果不掌握它们,很难写出高水平的程序。程序人人都会写,但当你发现写到一定程度很难再提高的时候,就应该想想是不是要回过头来学学这些最基本的理论。不要一开始就去学OOP,即使你再精通OOP,遇到一些基本算法的时候可能也会束手无策。因此多读一些计算机基础理论方面的书籍是非常有必要的。

MySQL助理配置 - 2016-09-23 14:09:05

基本配置   你需要经常察看以下3个配置项。不然,可能很快就会出问题。 innodb_buffer_pool_size:这是你安装完InnoDB后第一个应该设置的选项。缓冲池是数据和索引缓存的地方:这个值越大越好,这能保证你在大多数的读取操作时使用的是内存而不是硬盘。典型的值是5-6GB(8GB内存),20-25GB(32GB内存),100-120GB(128GB内存)。 innodb_log_file_size:这是redo日志的大小。redo日志被用于确保写操作快速而可靠并且在崩溃时恢复。一直到MyS
9个基于Java的搜索引擎框架   1.Java全文搜索引擎框架Lucene   毫 无疑问,Lucene是目前最受欢迎的Java全文搜索框架,准确地说,它是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引 擎。Lucene为开发人员提供了相当完整的工具包,可以非常方便地实现强大的全文检索功能。下面有几款搜索引擎框架也是基于Lucene实现的。 官方网站: http://lucene.apache.org/   2.开源Java搜索引擎Nutch   Nutch 是一个开源Java实

Quartz定时任务的实现及详解 - 2016-09-23 04:09:09

Quartz定时任务的实现及详解 平常工作中经常遇到写定时任务的,这次做一次记录和解析分享给大家,共同学习进步,遇到写的不对的地方也请大家指教 用例:比如每天凌晨我们要让系统定时执行一些耗费服务器的事情,或者其他的一些定时任务 相关的jar包在附件,如有需要自行下载 1、 首先怎么启动这个Quartz呢? 在项目启动的时候,让web.xml读取我们的定时器配置文件,如下所示 param-namecontextConfigLocation/param-nameparam-value/WEB-INF/conf

JDBC连接数据库的步骤详解 - 2016-09-23 04:09:09

   Java Code  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 8
编译Qconf git clone https://github.com/Qihoo360/QConf.git cd Qconf //注意如果不是root永恒,可能需要使用sudo权限 mkdir build cd build // 默认安装在/usr/local/qconf目录,后面的命令指定安装目录 cmake ..  或者 cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix make make install //如果出错,也就下面几个错误了 sudo l

Java 使用默认浏览器打开 URL - 2016-09-22 19:09:07

      URI uri = new URI(url);Desktop desktop = Desktop.getDesktop();if (desktop.isSupported(Desktop.Action.BROWSE)) {desktop.browse(uri);}            

Java线程Dump分析工具--jstack - 2016-09-22 18:09:03

Java线程Dump分析工具--jstack jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:      jstack [-l][F] pid      如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另

java spring整合websocket - 2016-09-21 17:09:03

这几天项目中需要整合websocket来支持业务,从网上看了好多资料。但是都很杂乱,我尝试了好多回,走了很多弯路,跳了很多坑~~~~~~。通过两天的调试终于成功!!!现在把调试步骤和容易出现的问题都列出来,让和我这样的新手有点帮助。开始上代码......... 【 备注:spring的版本4.0+ ,tomcat :7.50 + , jdk:1.8 】 java Spring 整合 websocket 有两种方法 : 1:配置方法 [网上有很多] (地址: http://blog.csdn.net/sti