一、webservice是什么:webservice接口实际上就是http协议+soap协议,通过http请求把soap报文发送到对方服务器,然后对方服务器也是通过http请求把soap报文返回。
二、技术选型:
webservice接口开发有Axis2,Apche CXF和http等方式。
1.Axis2 技术老旧,使用不便,不推荐。
2.在有大量的webservice接口的情况下,不建议使用http请求方式,http请求方式需要对每一个webservice接口的soap报文进行解析,比较麻烦。推荐使用 Apche CXF,操作简单。
3.webservice服务数量比较少,且不希望引入Apche CXF这种第三方的jar包时可以直接使用http请求的方式。
三、通过http请求webservice服务
阅读本地代码前需要先学习一下soapUI这个工具,soapUI这个工具可以直接把webservice地址放到请求地址上面,就能够知道对应的soap报文是什么了。并且能够知道响应结果的soap报文。
本例子适合webservice启用了账号密码验证的情况,如果无需账号密码验证,只需要删掉验证代码即可。
package com.utils.sapxml;
import com.utils.JaxbUtil;
import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
/**
* 发送把SAP数据的soap报文到SAP系统的工具类
*/
public class SapUtils {
private static Logger logger = LoggerFactory.getLogger(SapUtils.class);
/**
* 获取SAP接口的soap报文
*
* @param dataList
* @param fileList
* @return
*/
private static String getSAPXml(String dataList, String fileList) {
String soaoXML = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:doa=\"http://www.dfl.com.cn/DOA\">" +
" <soapenv:Header/>" +
" <soapenv:Body>" +
" <doa:MT_OA2SAP_MM44_SND>" +
dataList + fileList +
" </doa:MT_OA2SAP_MM44_SND>" +
" </soapenv:Body>" +
"</soapenv:Envelope>";
return soaoXML;
}
/**
* 发送post请求
* @param url 服务器地址
* @param userName 账号
* @param password 密码
* @param body xml报文体
* @return
* @throws IOException
* @throws URISyntaxException
*/
private static String sendHttpPost(String url, String userName, String password, String body) throws IOException, URISyntaxException {
String UTF8 = "UTF-8";
URI serverURI = new URI(url);
// 身份认证
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(
new AuthScope(serverURI.getHost(), serverURI.getPort()),
new UsernamePasswordCredentials(userName, password));
CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credProvider).build();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(new StringEntity(body, UTF8));
// 发送请求
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
// 获取请求结果
String responseContent = EntityUtils.toString(entity, UTF8);
response.close();
httpClient.close();
return responseContent;
}
/**
* xml格式化,消除转义字符
*
* @param inputXML
* @return
* @throws Exception
*/
private static String formatXml(String inputXML) throws Exception {
String xml = null;
SAXReader reader = new SAXReader();
XMLWriter writer = null;
Document document = reader.read(new StringReader(inputXML));
try {
if (document != null) {
StringWriter stringWriter = new StringWriter();
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter(stringWriter, format);
// 取消转义
writer.setEscapeText(false);
writer.write(document);
writer.flush();
xml = stringWriter.getBuffer().toString();
}
} finally {
if (writer != null) {
try {
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return xml;
}
/**
* 发送SAP报文
* @param url
* @param userName
* @param password
* @param dataXml
* @param fileXml
* @return
* @throws Exception
*/
public static String send(String url, String userName, String password,String dataXml, String fileXml) throws Exception {
//封装请求体
String xmlRequest = getSAPXml(dataXml, fileXml);
// 格式化
String xmlRequest2 = formatXml(xmlRequest);
logger.info("【SAP报文】>>>>:{}:", xmlRequest2);
//获取请求结果
String xmlRequestFormat = sendHttpPost(url, userName, password, xmlRequest2);
logger.info("【SAP报文】返回结果>>>>:{}:", xmlRequestFormat);
//xml格式化
String result = formatXml(xmlRequestFormat);
return result;
}
/**
* 发送请求, 且获取返回结果
* 测试方法
*
* @return
*/
public String execImpexpPaymentService() {
String url = "填写webservice的url";
String resultText = "";
try {
SapData data = new SapData();
data.setErrorMonth("2022-01");
data.setBukrs("1");
String dataStr = JaxbUtil.convertToXml(data);
SapFile file = new SapFile();
file.setErrorMonth("2022-01");
String fileStr = JaxbUtil.convertToXml(file);
logger.info("【测试】接口调用>>>>:arg0:{},arg1:{}", dataStr, fileStr);
//封装请求体
String xmlRquest = getSAPXml(dataStr, fileStr);
String xmlRquest2 = formatXml(xmlRquest);
//获取请求结果
String xmlRquestFormat = sendHttpPost(url, "WSUSER", "WSPASS", xmlRquest2);
//xml格式化
String result = formatXml(xmlRquestFormat);
logger.info("【测试】接口结果>>>>result:{}:", result);
} catch (Exception e) {
e.printStackTrace();
}
return resultText;
}
public static void main(String[] args) {
SapUtils httpUtil = new SapUtils();
httpUtil.execImpexpPaymentService();
}
}
package com.utils;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
/**
* 把java对象转换为xml报文
*/
public class JaxbUtil {
/**
* JavaBean转换成xml
* 默认编码UTF-8
* @param obj bean对象
* @return xml报文
*/
public static String convertToXml(Object obj) {
return convertToXml(obj, "UTF-8");
}
/**
* JavaBean转换成xml
* @param obj bean对象
* @param encoding 编码
* @return xml报文
*/
public static String convertToXml(Object obj, String encoding) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
// 是否省略xml头信息
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}