因项目需要调用webservice接口,一番研究后找到一个相对舒服的方法,下面一一介绍:
首先pom.xml加入
org.apache.axis
axis-jaxrpc
1.4
org.apache.cxf
cxf-spring-boot-starter-jaxws
3.2.4
习惯性写个获取配置文件中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入参
* @param method 方法名
*
*/
public static String transfer(String method,Map 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入参
* @param method 方法名
*
*/
public static boolean esPeripheralFeedback(String method,Map 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