公司web项目需要调用erp接口,格式是webservice格式,认证方式是用户名和密码,请求参数拼成一个webservice格式,接口调用返回解析成json格式,需要调用两个包,json包,dom4j包。
需要导入的包
com.alibaba
fastjson
1.2.46
dom4j
dom4j
1.6.1
1.创建一请求参数个实体类
package com.fashion.pojo;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* ......................................
* .没有才怎么怀才不遇,没有志怎么壮志难酬 .
* . ....................................
*
*@Author: lq
*@Date: 2018/10/10 16:23
*@Description: soap请求实体类-》对应数据库
*/
@Getter
@Setter
public class SOAPClientPojo {
private String wsdlLocation;//url地址
private String targetNamespace;//命名空间
private String serviceName;
private String portName;
//private String bindingType;
private String action;
private String prefix;
private Date createDate;//创建时间
private Date modifyDate;//修改时间
private Integer id;//主键
private String code;//接口唯一主键
private String userName;//用户名
private String password;//密码
}
2.调用接口核心逻辑
package com.fashion.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fashion.constant.WebserviceConstants;
import com.fashion.pojo.SOAPClientPojo;
import com.sun.xml.internal.ws.client.BindingProviderProperties;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.io.DOMReader;
import org.w3c.dom.Document;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
/**
* ......................................
* .没有才怎么怀才不遇,没有志怎么壮志难酬 .
* . ....................................
*
*@Author: lq
*@Date: 2018/10/10 16:29
*@Description: 调用webservice接口
*/
@Log
public class SOAPWebserviceUtil {
private static Dispatch dispatch;
private static MessageFactory messageFactory;
//获取分发对象
public static void init(SOAPClientPojo clientPojo) {
String targetNamespace = clientPojo.getTargetNamespace();
//初始化端口
QName portQName = new QName(targetNamespace,clientPojo.getPortName());
//初始化服务端口
QName serviceQName = new QName(targetNamespace, clientPojo.getServiceName());
//通过服务名创建服务对象
Service service = Service.create(serviceQName);
//向服务上添加一个新的端口
service.addPort(portQName, WebserviceConstants.SOAP11HTTP_BINDING,clientPojo.getWsdlLocation());
// 创建一个分发实例Dispatch
dispatch = service.createDispatch(portQName,SOAPMessage.class,Service.Mode.MESSAGE);
Map requestContext = dispatch.getRequestContext();
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT,WebserviceConstants.CONNECT_TIMEOUT);
//设置连接时间
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT,WebserviceConstants.SOCKET_TIMEOUT);
if (StringUtils.isNotBlank(clientPojo.getUserName()) && StringUtils.isNotBlank(clientPojo.getPassword())) {
requestContext.put(BindingProvider.USERNAME_PROPERTY,clientPojo.getUserName());
requestContext.put(BindingProvider.PASSWORD_PROPERTY,clientPojo.getPassword());
}
SOAPBinding soapBinding = (SOAPBinding) dispatch.getBinding();
messageFactory = soapBinding.getMessageFactory();
}
//调用webService方法,填充内容
public static JSONObject callWebService(SOAPClientPojo clientPojo,JSON reData) {
JSONObject result = new JSONObject();
try {
init(clientPojo);
SOAPMessage request = messageFactory.createMessage();
//创建soap消息主体
SOAPPart soapPart = request.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
String targetNamespace = clientPojo.getTargetNamespace();
String prefix = clientPojo.getPrefix();
String action = clientPojo.getAction();
//创建命名空间
soapEnvelope.addNamespaceDeclaration(prefix,targetNamespace);
//创建消息body内容
SOAPBody soapBody = soapEnvelope.getBody();
QName payloadName = new QName(targetNamespace, action, prefix);
SOAPElement bodyElement = soapBody.addChildElement(payloadName);
//请求参数
generateParams(bodyElement,reData);
//保存消息
request.saveChanges();
// 打印客户端发出的soap报文,做验证测试
ByteArrayOutputStream in = new ByteArrayOutputStream();
request.writeTo(in);
//TODO:此处到时候存入数据库
String message = new String(in.toByteArray());
log.info("客户端发送内容:" + message);
//通过Dispatch传递消息,会返回响应消息
SOAPMessage response = dispatch.invoke(request);
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.writeTo(out);
//TODO:此处到时候存入数据库
log.info("服务端响应内容:" + new String(out.toByteArray()));
//处理响应消息,将响应的消息转换为dom对象
SOAPBody responseBody = response.getSOAPPart().getEnvelope().getBody();
//org.w3c.dom.
Document document = responseBody.extractContentAsDocument();
// org.w3c.dom.装维dom4j
DOMReader xmlReader = new DOMReader();
org.dom4j.Document dom = xmlReader.read(document);
dom4j2Json(dom.getRootElement(), result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static void generateParams(SOAPElement payload, JSON params) throws SOAPException {
if (params instanceof JSONObject) {
JSONObject obj = (JSONObject) params;
for (String key : obj.keySet()) {
if (obj.get(key) instanceof JSONObject) {
SOAPElement soapElement = payload.addChildElement(key);
generateParams(soapElement, (JSON) obj.get(key));
} else if (obj.get(key) instanceof JSONArray) {
JSONArray ary = ((JSONArray) obj.get(key));
for (Object ar : ary) {
SOAPElement soapElement = payload.addChildElement(key);
generateParams(soapElement, (JSON) ar);
}
} else {
payload.addChildElement(key).setValue(obj.get(key) == null ? "" : obj.get(key).toString());
}
}
}
if (params instanceof JSONArray) {
JSONArray ary = ((JSONArray) params);
for (Object obj : ary) {
generateParams(payload, (JSON) obj);
}
}
}
//将dom4j转为json对象
private static void dom4j2Json(Element element, JSONObject json) {
//如果是属性
for (Object o : element.attributes()) {
Attribute attr = (Attribute) o;
if (StringUtils.isNotEmpty(attr.getValue())) {
json.put("@" + attr.getName(), attr.getValue());
}
}
List chdEl = element.elements();
if (chdEl.size() == 0) {
//如果没有子元素,只有一个值 null值也放入JSON
log.info(element.getName());
log.info(element.getText());
json.put(element.getName(), element.getText());
} else {
for (Element e : chdEl) {
if (!e.elements().isEmpty()) {
//子元素也有子元素
JSONObject chdjson = new JSONObject();
dom4j2Json(e, chdjson);
Object o = json.get(e.getName());
if (o != null) {
JSONArray jsona = null;
if (o instanceof JSONObject) {
//如果此元素已存在,则转为jsonArray
JSONObject jsono = (JSONObject) o;
json.remove(e.getName());
jsona = new JSONArray();
jsona.add(jsono);
jsona.add(chdjson);
}
if (o instanceof JSONArray) {
jsona = (JSONArray) o;
jsona.add(chdjson);
}
json.put(e.getName(), jsona);
} else {
if (!chdjson.isEmpty()) {
json.put(e.getName(), chdjson);
} else {
json.put(e.getName(), null);
}
}
} else {
//子元素没有子元素
for (Object o : element.attributes()) {
Attribute attr = (Attribute) o;
if (StringUtils.isNotEmpty(attr.getValue())) {
json.put("@" + attr.getName(), attr.getValue());
}
}
json.put(e.getName(), e.getText());
}
}
}
}
}
public static final String SOAP11HTTP_BINDING = "http://schemas.xmlsoap.org/wsdl/soap/http";
public static final Integer CONNECT_TIMEOUT = 600000;//默认的连接超时时间(毫秒)
//从connect Manager获取Connection的默认超时时间(毫秒)
public static final Integer CONNECTION_REQUEST_TIMEOUT = 600000;
1.参数说明: 将webservice地址放到浏览器直接回车可以看到location地址
2.其余参数也需要在浏览器中找。
3.接口参数封装为json格式,如下 reData
4.以下为参数说明
补充:prefix和action需要借助soapui来获得,以下有详细文档说明参数的获取,点开链接自己去下载。
参数详情获取方法,点击链接可去下载
如有问题:QQ:83567827