WebService tool class (called by SpringBoot environment)

The following tools integrate multiple ways to call webservice, such as http method, axis method, dynamic client generation method, etc. They are refined for bloggers' actual work and are convenient for everyone to apply directly. Common methods are listed with calling examples.

1. The entire tool code

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 <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T call(String url,String soapActionURI, String nameSpace,String operationName, Map<String, String> params, Class<T> 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<String> parameterList = Lists.newArrayList();
            if (params != null) {
                Set<String> 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<String, String> 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<String> parameterList = Lists.newArrayList();
            if (params != null) {
                Set<String> 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<String, String> params,
                                                       Map<String,String> 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<String> parameterList = Lists.newArrayList();
            //设置参数模式处理函数
            Function<String,ParameterMode> function = (key)->{
                if("OUT".equals(key)){
                    return ParameterMode.OUT;
                }
                return ParameterMode.IN;
            };
            if (params != null) {
                Set<String> 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<String, String> 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<String> parameterList = Lists.newArrayList();
            if (params != null) {
                Set<String> 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<schemaResult.get_any().length; i++){
                result.append(schemaResult.get_any()[i]);
            }
            log.error("调用 WebService 接口返回===>" + 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;
    }
}

2. Introduction of pom dependencies

There may be too many copied dependencies, you can try to remove them yourself, as long as the tool class does not become red and report errors.

        <dependency>
            <groupId>javax.jws</groupId>
            <artifactId>javax.jws-api</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.ws</groupId>
            <artifactId>jaxws-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-xjc</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.1.11</version>
        </dependency>
        <!--axis-->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>

3. Detailed explanation of method call list

 3.1 The following call is the second method of the tool class. What is returned is a string string. Specifically, whether it is json or xml, it can be parsed according to the actual situation.

Specific parameter explanation

* @param url third-party service address
* @param soapActionURI Baidu soapAction
* @param nameSpace namespace, self-Baidu soap
* @param operationName calling method name
* @param params calling parameters, the example parameter name is xml

3.2 Next is the dcfSoap() method

* Dynamically call webService
* @param url third-party service address
* @param operationName method name
* @param params dynamic parameters, you can write multiple

3.3 HttpSendSoapPost (This method is the most commonly used, but the message header needs to be assembled by yourself. I usually use the soapUI tool to connect to the other party's service, which will be automatically generated, and the parameters will be spliced ​​by myself. This call is unlikely to cause any messy problems)

 1 is to build xml, 2 is to put xml in the parameters of the message header generated by soapui, 3 is to directly call the tool class to send

If you really don’t know how to call it, just ask me in the comment area.

Guess you like

Origin blog.csdn.net/weixin_40141628/article/details/132876630