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;
}
部分代码参考网上写法,此处只做一个汇总!