以下工具集成了多种方式调用webservice,如http方式,axis方式,动态生成客户端方式等 ,是为博主实际工作中提炼的,方便大家直接套用,常用方法都有调用示列。
package com.gykjit.spd.edi.util; 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.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.encoding.ser.BeanSerializerFactory; import org.apache.axis.message.SOAPHeaderElement; import org.apache.axis.types.Schema; import org.apache.commons.collections.MapUtils; import com.google.common.collect.Lists; import org.springframework.util.StringUtils; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; /** * @author hulei * @Date 2022/9/8 18:31 */ public class WebServiceUtil { private final static Logger log = LoggerFactory.getLogger(WebServiceUtil.class); /** * * @param url * @param soapActionURI * @param nameSpace * @param operationName * @param params * @param clazz * @param* @return */ @SuppressWarnings("unchecked") public static T call(String url,String soapActionURI, String nameSpace,String operationName, Map params, Class clazz) { soapActionURI = StringUtils.isEmpty(soapActionURI)? nameSpace + operationName :soapActionURI; try { Service service = new Service(); SOAPHeaderElement header = new SOAPHeaderElement(nameSpace, operationName); header.setNamespaceURI(nameSpace); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(new QName(nameSpace, operationName)); // 添加参数 List parameterList = Lists.newArrayList(); if (params != null) { Set paramsKey = params.keySet(); for (String key : paramsKey) { call.addParameter(new QName(nameSpace, key), XMLType.XSD_STRING, ParameterMode.IN); String pValue = MapUtils.getString(params, key); header.addChildElement(key).setValue(pValue); parameterList.add(pValue); } } call.setUseSOAPAction(true); call.setSOAPActionURI(soapActionURI); call.addHeader(header); //进行序列化 实体类也要序列化 implements Serializable call.registerTypeMapping(clazz, new QName(nameSpace, soapActionURI), new BeanSerializerFactory(clazz, new QName(nameSpace, soapActionURI)), new BeanDeserializerFactory(clazz, new QName(nameSpace, soapActionURI))); //设置输出的类 call.setReturnClass(clazz); // 接口返回结果 T result = (T) call.invoke(parameterList.toArray()); log.info("调用 WebService 接口返回===>" + result); return result; } catch (Exception e) { log.error("调用 WebService 接口错误信息==>" + e.getMessage()); } return null; } /** * * @param url * @param soapActionURI * @param nameSpace * @param operationName * @param params * @return */ public static String call(String url,String soapActionURI,String nameSpace,String operationName, Map params) { soapActionURI = StringUtils.isEmpty(soapActionURI)? nameSpace + operationName :soapActionURI; try { Service service = new Service(); SOAPHeaderElement header = new SOAPHeaderElement(nameSpace, operationName); header.setNamespaceURI(nameSpace); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(new QName(nameSpace, operationName)); // 添加参数 List parameterList = Lists.newArrayList(); if (params != null) { Set paramsKey = params.keySet(); for (String key : paramsKey) { call.addParameter(new QName(nameSpace, key), XMLType.XSD_STRING, ParameterMode.IN); String pValue = MapUtils.getString(params, key); header.addChildElement(key).setValue(pValue); parameterList.add(pValue); } } call.setUseSOAPAction(true); call.setSOAPActionURI(soapActionURI); call.addHeader(header); // 设置返回类型 call.setReturnType(new QName(nameSpace, operationName), String.class); // 接口返回结果 String result = (String) call.invoke(parameterList.toArray()); log.info("调用 WebService 接口返回===>" + result); return result; } catch (Exception e) { log.error("调用 WebService 接口错误信息==>" + e.getMessage()); } return null; } /** * 设置参数模式(IN,OUT) * @param url * @param soapActionURI * @param nameSpace * @param operationName * @param params * @param ParameterModeType 参数模式(IN,OUT) * @return */ public static String callAndSetParameterModeType(String url,String soapActionURI,String nameSpace,String operationName, Map params, Map ParameterModeType) { soapActionURI = StringUtils.isEmpty(soapActionURI)? nameSpace + operationName :soapActionURI; try { Service service = new Service(); SOAPHeaderElement header = new SOAPHeaderElement(nameSpace, operationName); header.setNamespaceURI(nameSpace); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(new QName(nameSpace, operationName)); // 添加参数 List parameterList = Lists.newArrayList(); //设置参数模式处理函数 Function function = (key)->{ if("OUT".equals(key)){ return ParameterMode.OUT; } return ParameterMode.IN; }; if (params != null) { Set paramsKey = params.keySet(); for (String key : paramsKey) { call.addParameter(new QName(nameSpace, key), XMLType.XSD_STRING,function.apply(MapUtils.getString(ParameterModeType, key))); String pValue = MapUtils.getString(params, key); header.addChildElement(key).setValue(pValue); parameterList.add(pValue); } } call.setUseSOAPAction(true); call.setSOAPActionURI(soapActionURI); call.addHeader(header); // 设置返回类型 call.setReturnType(new QName(nameSpace, operationName), String.class); // 接口返回结果 String result = (String) call.invoke(parameterList.toArray()); log.info("调用 WebService 接口返回===>" + result); return result; } catch (Exception e) { log.error("调用 WebService 接口错误信息==>" + e.getMessage()); } return null; } /** * WebService - 调用接口 * * @param operationName 函数名 * @param params 参数 * @return 返回结果(String) */ public static String callReturnSchema(String url,String soapActionURI,String nameSpace,String operationName, Map params) { soapActionURI = StringUtils.isEmpty(soapActionURI)? nameSpace + operationName :soapActionURI; try { Service service = new Service(); SOAPHeaderElement header = new SOAPHeaderElement(nameSpace, operationName); header.setNamespaceURI(nameSpace); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(new QName(nameSpace, operationName)); // 添加参数 List parameterList = Lists.newArrayList(); if (params != null) { Set paramsKey = params.keySet(); for (String key : paramsKey) { call.addParameter(new QName(nameSpace, key), XMLType.XSD_STRING, ParameterMode.IN); String pValue = MapUtils.getString(params, key); header.addChildElement(key).setValue(pValue); parameterList.add(pValue); } } call.setUseSOAPAction(true); call.setSOAPActionURI(soapActionURI); call.addHeader(header); // 设置返回类型 call.setReturnType(XMLType.XSD_SCHEMA); // 接口返回结果 Schema schemaResult = (Schema)call.invoke(parameterList.toArray()); StringBuilder result = new StringBuilder(); for(int i = 0; i " + result); return result.toString(); } catch (Exception e) { log.error("调用 WebService 接口错误信息==>" + e.getMessage()); } return null; } /** * 动态调用webService * @param url * @param operationName * @param params * @return * @throws Exception */ public static Object dcfSoap(String url, String operationName, String... params) throws Exception { /// 创建动态客户端 JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient(url); //超时等待设置,防止处理时间过长断开连接 HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); long timeout = 10 * 60 * 1000; policy.setConnectionTimeout(timeout);//连接时间 policy.setReceiveTimeout(timeout);//接受时间 conduit.setClient(policy); // 需要密码的情况需要加上用户名和密码 // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD)); Object[] objects; try { // invoke("方法名",参数1,参数2,参数3....); //这里注意如果是复杂参数的话,要保证复杂参数可以序列化 objects = client.invoke(operationName, (Object) params); System.out.println("返回数据:" + objects[0]); } catch (java.lang.Exception e) { log.info("返回数据异常:"+e.getMessage()); return e.getMessage(); } return objects[0]; } /** * http方式调用webService * @param wsdlUrl 远程地址 * @param SOAPAction 标识http请求目的地 * @param soapXml 请求参数 * @return 返回的是soap报文(可用dom4j解析) */ public static String HttpSendSoapPost(String wsdlUrl,String SOAPAction,String soapXml){ HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; String result = null;// 返回结果字符串 OutputStream out; try { // 创建远程url连接对象 URL url = new URL(wsdlUrl); // 通过远程url连接对象打开一个连接,强转成httpURLConnection类 connection = (HttpURLConnection) url.openConnection(); // 设置连接方式:GET,POST connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); //这里必须要写,否则出错,根据自己的要求写,默认为空 connection.setRequestProperty("SOAPAction", SOAPAction != null ? SOAPAction : ""); // 设置连接主机服务器的超时时间:15000毫秒 connection.setConnectTimeout(15000); // 设置读取远程返回的数据时间:200000毫秒 connection.setReadTimeout(200000); // 发送请求 connection.connect(); out = connection.getOutputStream(); // 获取输出流对象 connection.getOutputStream().write(soapXml.getBytes(StandardCharsets.UTF_8)); // 将要提交服务器的SOAP请求字符流写入输出流 out.flush(); out.close(); // 通过connection连接,获取输入流 if (connection.getResponseCode() == 200) { is = connection.getInputStream(); // 封装输入流is,并指定字符集 br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); // 存放数据 StringBuilder sbf = new StringBuilder(); String temp; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } // 关闭远程连接 if(connection != null){ connection.disconnect(); } } return result; } public static String sendWebService(String url, String xml) { try { URL soapUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) soapUrl.openConnection(); connection.setRequestMethod("POST"); connection.setUseCaches(false); //设置输入输出,新创建的connection默认是没有读写权限的 connection.setDoInput(true); connection.setDoOutput(true); //这里设置请求头类型为xml,传统http请求的是超文本传输格式text/html connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); connection.getOutputStream().write(xml.getBytes(StandardCharsets.UTF_8)); // 将要提交服务器的SOAP请求字符流写入输出流 log.info("写入xml入参:{}", xml); InputStream inputStream = connection.getInputStream(); if (inputStream != null) { byte[] bytes; bytes = new byte[inputStream.available()]; int result = inputStream.read(bytes); if(result == -1){ log.info("流读取完毕!"); } //将字节数组转换为字符串输出 return new String(bytes, StandardCharsets.UTF_8); } } catch (Exception e) { log.info("sendWebService方法报错:{}", e.getMessage()); return null; } return null; } }
可能有复制多了的依赖,可自己尝试去除,工具类不飘红报错就行
javax.jws javax.jws-api1.1 javax.xml.ws jaxws-api2.3.1 cn.hutool hutool-all5.4.1 com.sun.xml.bind jaxb-xjc2.2.11 org.apache.cxf cxf-rt-transports-http3.1.11 org.apache.cxf cxf-rt-frontend-jaxws3.1.11 org.apache.axis axis1.4 org.apache.axis axis-jaxrpc1.4 org.dom4j dom4j2.1.1 jaxen jaxen1.2.0
3.1 以下调用的是工具类第二个方法,返回的是string字符串,具体是json还是xml,按照实际情况解析就行
具体参数解释
* @param url 第三方服务地址 * @param soapActionURI 自行百度soapAction * @param nameSpace 命名空间,自行百度soap * @param operationName 调用方法名 * @param params 调用参数,示例的参数名是xml
3.2 接着是 dcfSoap()方法
* 动态调用webService * @param url 第三方服务地址 * @param operationName 方法名 * @param params 动态参数,可以写多个
3.3 HttpSendSoapPost(此方法最常用,但是报文头需要自己拼,我一般用soapUI工具连好对方服务,会自动生成,参数自己拼接上,这个调用不太会出现一些乱七八糟的问题)
1是构建xml,2是把xml放在soapui生成的报文头的参数里,3直接调用工具类发送
实在不会调用的,评论区找我吧