CXF动态调用webservice接口传递复杂参数

时间: 2023-08-15 admin 互联网

CXF动态调用webservice接口传递复杂参数

CXF动态调用webservice接口传递复杂参数

因项目需要调用webservice接口,一番研究后找到一个相对舒服的方法,下面一一介绍:

首先pom.xml加入

        <!-- CXF调用接口 -->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
            <version>3.2.4</version>
        </dependency>

习惯性写个获取配置文件中wsdl地址:

static {
                //application.properties或者application.yml
		String path = File.separator + "application.properties";
		ClassPathResource resource = new ClassPathResource(path);
		try {
			Properties props = PropertiesLoaderUtils.loadProperties(resource);
			wsdlUrl = (String) props.get("wsdlUrl");
		} catch (IOException e) {
			e.printStackTrace();
		}
		logger.info("初始化cxf调用webservice地址为:" + wsdlUrl);
	}

我这里传入的是实体对象,首先需要在本地创建一个相应的实体类,包路径要与服务端实体类路径一致

//CXF传入复杂参数:调用服务器端实体类->调用set方法->提交参数
// 加载类为服务端自定义对象命名空间
Object ajjySjth = Thread.currentThread().getContextClassLoader().loadClass("你的实体类地址").newInstance();
// 调用set方法设置参数
Method setAccNbr = ajjySjth.getClass().getMethod("setAccNbr", String.class);
//添加参数
setAccNbr.invoke(ajjySjth, s.get("accNbr"));
paramsStr = om.writeValueAsString(ajjySjth);
//调用接口,传入参数(method:调用webservice方法名,ajjySjth:传入实体对象)
objects = client.invoke(method, ajjySjth);

我这有点特殊还遇到了实体类中包含其他实体对象,这种情况下:

//CXF传入复杂参数:调用服务器端实体类实体中存在其他实体对象->先调用被包含实体对象->调用set方法->提交参数->调用传递实体对象->调用set方法->提交参数
Object ajjySjth2 = Thread.currentThread().getContextClassLoader().loadClass("server.FeedbackEvent").newInstance();// 加载类为服务端自定义对象命名空间
Method setContactResultNo = ajjySjth2.getClass().getMethod("setContactResultNo", int.class);// 调用set方法设置参数
setContactResultNo.invoke(ajjySjth2, 0);
paramsStr = om.writeValueAsString(ajjySjth2);
Object ajjySjth = Thread.currentThread().getContextClassLoader().loadClass("server.PeripheralFeedback").newInstance();// 加载类为服务端自定义对象命名空间
Method setAccNbr = ajjySjth.getClass().getMethod("setAccNbr", String.class);// 调用set方法设置参数
Method setFeedbackEvent = ajjySjth.getClass().getMethod("setFeedbackEvent", FeedbackEvent.class);// 调用set方法设置参数
setAccNbr.invoke(ajjySjth, s.get("accNbr"));
//其他实体对象参数为调用的加载服务器端实体实例
setFeedbackEvent.invoke(ajjySjth, ajjySjth2);	
paramsStr = om.writeValueAsString(ajjySjth);

logger.info("cxf 调用webservice method:" + method + ",参数:" + paramsStr);

objects = client.invoke(method, ajjySjth);

如果是普通参数直接放入

//调用接口,传入参数(method:调用方法名,ajjySjth:参数)
objects = client.invoke(method, ajjySjth);

最后贴上代码

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import net.sf.json.JSONObject;

public class CxfInvokeUtil {
	static Logger logger = LoggerFactory.getLogger(CxfInvokeUtil.class);
	private static String wsdlUrl = "";
	private static Client client=null;
	static {

		String path = File.separator + "application.yml";
		ClassPathResource resource = new ClassPathResource(path);
		try {
			Properties props = PropertiesLoaderUtils.loadProperties(resource);
			wsdlUrl = (String) props.get("wsdlUrl");
		} catch (IOException e) {
			e.printStackTrace();
		}
		logger.info("初始化cxf调用webservice地址为:" + wsdlUrl);
	}

	/**
	 *
	 * 	CXF动态调用
	 *
	 */
	public static synchronized boolean create() {
		try {

			JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
			client = dcf.createClient(wsdlUrl);

			// 如果返回的address不是远程服务地址,重新制定地址
			client.getEndpoint().getEndpointInfo().setAddress(wsdlUrl);

			HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); // 策略
			httpClientPolicy.setConnectionTimeout(6000000); // 连接超时
			httpClientPolicy.setAllowChunking(false);
			httpClientPolicy.setReceiveTimeout(6000000); // 接收超时
			HTTPConduit http = (HTTPConduit) client.getConduit();
			http.getClient().setReceiveTimeout(0);
			http.setClient(httpClientPolicy);
			if(null != client) {
				return true;
			}			
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("cxf 调用webservice 执行错误:", e);
			return false;
		}
		return false;
	}
	
	/**
	 * @param Map<String, Object>入参
	 * @param method 方法名
	 * 
	 */
	public static String transfer(String method,Map<String, Object> s) {
		Object[] objects = null;
		String paramsStr = "";
		if (CxfInvokeUtil.create()) {
			ObjectMapper om = new ObjectMapper();
			try {
				//CXF传入复杂参数:调用服务器端实体类->调用set方法->提交参数
				Object ajjySjth = Thread.currentThread().getContextClassLoader().loadClass("server.QueryEventRelation").newInstance();// 加载类为服务端自定义对象命名空间
				Method setAccNbr = ajjySjth.getClass().getMethod("setAccNbr", String.class);// 调用set方法设置参数
				setAccNbr.invoke(ajjySjth, s.get("accNbr"));//用户号码
				paramsStr = om.writeValueAsString(ajjySjth);
				logger.info("cxf 调用webservice method:" + method + ",参数:" + paramsStr);
				//调用接口,传入参数
				objects = client.invoke(method, ajjySjth);
				if (objects[0] != null) {
					return objects[0].toString();
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error("cxf 调用webservice 执行错误:", e);
				return null;
			}
			
		}else {
			logger.info("cxf 调用webservice 失败");
		}
		return null;
	}
	
	/**
	 * @param Map<String, Object>入参
	 * @param method 方法名
	 * 
	 */
	public static boolean esPeripheralFeedback(String method,Map<String, Object> s) {
		Object[] objects = null;
		String paramsStr = "";
		if (CxfInvokeUtil.create()) {
			ObjectMapper om = new ObjectMapper();
			try {
				//CXF传入复杂参数:调用服务器端实体类实体中存在其他实体对象->先调用被包含实体对象->调用set方法->提交参数->调用传递实体对象->调用set方法->提交参数
				Object ajjySjth2 = Thread.currentThread().getContextClassLoader().loadClass("server.FeedbackEvent").newInstance();// 加载类为服务端自定义对象命名空间				
				Method setContactResultNo = ajjySjth2.getClass().getMethod("setContactResultNo", int.class);// 调用set方法设置参数
				setContactResultNo.invoke(ajjySjth2, s.get("contactResultNo"));//接触结果
				paramsStr = om.writeValueAsString(ajjySjth2);
				Object ajjySjth = Thread.currentThread().getContextClassLoader().loadClass("server.PeripheralFeedback").newInstance();// 加载类为服务端自定义对象命名空间
				Method setAccNbr = ajjySjth.getClass().getMethod("setAccNbr", String.class);// 调用set方法设置参数				
				setAccNbr.invoke(ajjySjth, s.get("accNbr"));
				//其他实体对象参数为调用的加载服务器端实体实例
				setFeedbackEvent.invoke(ajjySjth, ajjySjth2);	
				paramsStr = om.writeValueAsString(ajjySjth);
				
				logger.info("cxf 调用webservice method:" + method + ",参数:" + paramsStr);

				objects = client.invoke(method, ajjySjth);
				if(objects[0] != null){
					System.out.println(objects[0].toString());
					return true;
				}
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error("cxf 调用webservice 执行错误:", e);
				return false;
			}					
		}else {
			logger.info("cxf 调用webservice 失败");
		}
		return false;
	}

}

 

如果遇到错误

java.lang.IllegalStateException: Unable to create schema compiler

报错com.sun.tools.internal.xjc.api.XJC

问题:jre中缺少tools.jar

解决方法:java build path 设置为jdk


springboot整合cxf:传送门

结尾有项目代码地址