java中使用axis1调用远程webservice接口,参数中包括byte[][]和string[]

java中使用axis1调用远程webservice接口,参数中包括byte[][]和string[]

最近由于接了个需求,是需要访问外部一个webservice接口,由于传递附件使用到了byte[][]参数,一直传递失败,后查阅各种文章后解决,此处做一个总结,希望也能帮助到需要的小伙伴!(不要像我到处找解决方案,各种尝试,时间花费了不少)

总共2中方式:
1)axis(建议使用)
2)http(看情况考虑,参数需要拼接报文内容)

目标接口:
http://xxxxxxl?wsdl
目标接口如下:

public String create(String subject,byte[][] file, String[] fileName)

soapui中解析到的报文如下:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:DefaultNamespace" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
   <soapenv:Header/>
   <soapenv:Body><urn:create soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <subject xsi:type="xsd:string"></subject>
         <file xsi:type="urn:ArrayOf_soapenc_base64" soapenc:arrayType="xsd:byte[][]">
         </file>
         <fileName xsi:type="urn:ArrayOf_xsd_string" soapenc:arrayType="xsd:string[]">
          test122
         </fileName>
      </urn:create>
   </soapenv:Body>
</soapenv:Envelope>

axis方式

pom引入

       <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>axis</groupId>
            <artifactId>axis-wsdl4j</artifactId>
            <version>1.5.1</version>
        </dependency>
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.2</version>
        </dependency>

工具类

package com.sinopec.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.ArrayDeserializerFactory;
import org.apache.axis.encoding.ser.ArraySerializerFactory;
import org.apache.axis.encoding.ser.Base64DeserializerFactory;
import org.apache.axis.encoding.ser.Base64SerializerFactory;
import org.apache.axis.message.SOAPHeaderElement;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * WebService - 工具类
 *
 * @author
 * @date
 */
@Slf4j
public class WebServiceUtil {



    public static Result<?> call(String url, String namespace, String methodName, byte[][] file, List<String> fileNames) {
        String result = callNomal(url,namespace,methodName, params,file,fileNames);
//        String resultMock = callMock(url,namespace,methodName, params,file,fileNames);
        if(result == null){
           return Result.error("邮件处理失败");
        }
        if(!result.contains("成功处理完毕")){
            return Result.error(result);
        }
        return Result.success(result);
    }

    public static String callNomal(String url,String namespace,String methodName, byte[][] file,List<String> fileNames) {
        String[] names = fileNames.toArray(new String[fileNames.size()]);
        Object[] opAddEntryArgs = new Object[] {
                params.get("subject"),
                file,
                names};
        return callRemote(url,namespace,methodName,opAddEntryArgs);
    }

    /**
     * WebService - 接口调用
     *
     * @param methodName 函数名
     * @param params     参数
     * @return 返回结果(String)
     */
    public static String callRemote(String url,String namespace,String methodName, Map<String, String> params) {
//         log.info("调用 WebService 发送参数==>" + params.toString());
        String soapActionURI = namespace +"/"+ methodName;
        try {
            Service service = new Service();
            SOAPHeaderElement header = new SOAPHeaderElement(namespace, methodName);
            header.setNamespaceURI(namespace);
            Call call = (Call) service.createCall();
            call.setTargetEndpointAddress(url);
            call.setOperationName(new QName(namespace, methodName));

  
                    call.addParameter(new QName(namespace, ”file"), XMLType.SOAP_ARRAY, Byte[][].class, ParameterMode.IN);
                    call.addParameter(new QName(namespace, "fileName"), XMLType.SOAP_ARRAY,String[].class, ParameterMode.IN);
                    call.addParameter(new QName(namespace, "subject"), XMLType.SOAP_STRING, ParameterMode.IN);
              

            QName qn=new QName(namespace, methodName);
            //序列化与反序列化数组
            call.registerTypeMapping(String[].class, qn, new ArraySerializerFactory(), new ArrayDeserializerFactory());
            call.registerTypeMapping(byte[].class, qn, new Base64SerializerFactory(byte[].class, qn), new Base64DeserializerFactory(byte[].class, qn));
            call.registerTypeMapping(byte[][].class, qn, new Base64SerializerFactory(byte[][].class, qn), new Base64DeserializerFactory(byte[][].class, qn));
            call.setUseSOAPAction(true);
            call.setSOAPActionURI(soapActionURI);
            // 设置返回类型
            call.setReturnType(new QName(namespace, methodName), String.class);
            // 接口返回结果
            String result = (String) call.invoke(paramObject);
            log.info("调用 WebService 接口返回===>" + result);
            return result;
        } catch (Exception e) {
            log.error("调用 WebService 接口错误信息==>" + e.getMessage());
        }
        return null;
    }


    public static String callMock(String url,String namespace,String methodName, byte[][] file,List<String> fileNames) {
        //mock发送参数
        // 添加参数
        List fileNamesMock = new ArrayList<>();
        List<File> filesMock = new ArrayList<>();
        File file1 = new File("/Users/test.txt");
        fileNamesMock.add("test.txt");
        filesMock.add(file1);
        File file2 = new File("/Users/test.pdf");
        fileNamesMock.add("test.pdf");
        filesMock.add(file2);
        byte[][] filesBytesMock = new byte[filesMock.size()][];
        try{
            for(int i=0;i<filesMock.size();i++){
                File fileTemp = filesMock.get(i);
                FileInputStream fis = new FileInputStream(fileTemp);
                filesBytesMock[i] = new byte[(int) fileTemp.length()];
                fis.read(filesBytesMock[i]);
                fis.close();
            }
        }catch (Exception e){
            log.error("mock数据出错");
        }
        fileNames=fileNamesMock;
        file=filesBytesMock;

        /**-----------------mock结束----------------**/

        String[] names = fileNames.toArray(new String[fileNames.size()]);
        Object[] opAddEntryArgs = new Object[] {
                params.get("subject"),
                file,
                names };
        return callRemote(url,namespace,methodName,params,opAddEntryArgs);
    }
}

http方式

/**
     * 使用apache的HttpClient发送http请求
     * @param url     请求URL
     * @param content   请求参数:拼接好的报文(可借助soapui工具查看)
     * @Author:
     * @Date:
     * @return XML String
     */
    public Result<?> httpCilentPost(String url, String content) throws IOException {
        // 获得Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Post请求
        HttpPost httpPost = new HttpPost(url);
        // 将数据放入entity中
        StringEntity entity = new StringEntity(content, "UTF-8");
        httpPost.setEntity(entity);
        // 响应模型
        String result = null;
        CloseableHttpResponse response = null;
        try {
            //设置请求头
            //特别说明一下,此处为SOAP1.1协议
            //如果用的是SOAP1.2协议,改为:"application/soap+xml;charset=UTF-8"
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
            //命名空间+方法名
            //如为SOAP1.2协议不需要此项
            httpPost.setHeader("SOAPAction", eInvoiceProperties.getMail().getZthcMail().getMethod() );
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String back = EntityUtils.toString(responseEntity);
            result = parseResult(back);
            log.info("返回描述信息:" + result);
            log.info("返回状态码:" + response.getStatusLine().getStatusCode());
        } finally {
            // 释放资源
            if (httpClient != null) {
                httpClient.close();
            }
            if (response != null) {
                response.close();
            }
        }
        return Result.success(result);
    }

    /**
     * 解析返回结果
     * @param s
     * @return String
     */
    private static String parseResult(String s) {
        String result = "";
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new ByteArrayInputStream(s.getBytes()));
            Element response = (Element) document.getElementsByTagName("ns1:createResponse").item(0);
            result = response.getElementsByTagName("createReturn").item(0).getTextContent().trim();
        }catch (Exception e){
            log.error("解析xml结果异常",e.getMessage());
            e.printStackTrace();
        }

        return result;
    }

部分代码参考网上写法,此处只做一个汇总!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值