java调用webService 工具类
前言
最近也不清楚什么情况,项目中需要调用webservice,之前都是调用httpClient,第一次调用,特地记录一下,以便后面使用。原文出处忘了,不过接下来注释绝对尽量让一个初学者也能理解。
webService 的优势与不足
优点:
1 、采用xml支持跨平台远程调用。
2、基于http的soap协议,可跨越防火墙。
(因为SOAP一般使用HTTP协议,而服务器的这个协议一般都是开放的,而且是可以穿过防火墙的)
3、支持面向对象开发。
4、有利于软件和数据重用,实现松耦合。
缺点
由于soap是基于xml传输,本身使用xml传输会传输一些无关的东西从而效率不高,随着soap协议的完善,soap协议增加了许多内容,这样就导致了使用soap协议去完成简单的数据传输的效率不高。如果直接用http传输自定义数据内容比webservice开发更快捷,例如第三方支付公司的支持接口。
说到这我记得我当时问webService 的提供人,为什么不用 httpClient 接口调用方式,他回答的是这个是之前现成的。。。我也很无奈啊
工具类正文
说了那么多废话,还是来点真东西吧
SOAPWebserviceUtil
package com.sf.bpm.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sf.bpm.baseInfo.model.SOAPClientPojo;
import com.sun.xml.internal.ws.client.BindingProviderProperties;
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;
import java.util.logging.Logger;
public class SOAPWebserviceUtil {
private static Dispatch<SOAPMessage> dispatch;
private static MessageFactory messageFactory;
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;
private static Logger log = Logger.getLogger(SOAPWebserviceUtil.class.getName());
//获取分发对象
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, SOAP11HTTP_BINDING,clientPojo.getWsdlLocation());
// 创建一个分发实例Dispatch<SOAPMessage>
dispatch = service.createDispatch(portQName,SOAPMessage.class,Service.Mode.MESSAGE);
Map<String,Object> requestContext = dispatch.getRequestContext();
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT,CONNECT_TIMEOUT);
//设置连接时间
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT,CONNECTION_REQUEST_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<Element> 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());
}
}
}
}
}
工具类所需的model
SOAPClientPojo
package com.sf.bpm.baseInfo.model;
import java.util.Date;
public class SOAPClientPojo {
private String wsdlLocation;//url地址
private String targetNamespace;//命名空间 targetNamespace(访问webService找到对应的标签值)
private String serviceName; // 找借口提供人获取,或访问webService 查看
private String portName; //找port 标签,对应的name
//private String bindingType;
private String action; //operation 标签对应值
private String prefix; //前缀 用工具生成的参数查看action 标签前对应的值
private Date createDate;//创建时间
private Date modifyDate;//修改时间
private Integer id;//主键
private String code;//接口唯一主键
private String userName;//用户名
private String password;//密码
public String getWsdlLocation() {
return wsdlLocation;
}
public void setWsdlLocation(String wsdlLocation) {
this.wsdlLocation = wsdlLocation;
}
public String getTargetNamespace() {
return targetNamespace;
}
public void setTargetNamespace(String targetNamespace) {
this.targetNamespace = targetNamespace;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getPortName() {
return portName;
}
public void setPortName(String portName) {
this.portName = portName;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
到这里其实正文部分就已经结束了,接下看一下调用的示例
调用示例
@Override
public String pushMsgToPlm(Map map) {
logger.info("------------开始向PLM系统推送专利申请信息--------------");
String url = PropUtils.getValue("ZLSQ.PLM.URL");
String username = PropUtils.getValue("ZLSQ.PLM.USERNAME");
String password = PropUtils.getValue("ZLSQ.PLM.PASSWORD");
//根据TS_ID 获取需要传入的参数
Map patenApplication = getPatentApplication(map.get("TS_ID").toString());
List<Map<String , Object>> patentProductList = getPatentProduct(map.get("TS_ID").toString());
Map inst = getInst(map.get("TS_ID").toString());
List<Map> dataList = getFianlParm(inst,patenApplication,patentProductList);
Map resultMap = new HashMap();
resultMap.put("url", url);
resultMap.put("dataList", dataList);
SOAPClientPojo requestPojo = new SOAPClientPojo();
requestPojo.setWsdlLocation(url);
requestPojo.setTargetNamespace("http://ps.syscong.sfauto.ext/");
requestPojo.setServiceName("SFWebServiceInterface");
requestPojo.setPortName("SFWebServicePort");
requestPojo.setPrefix("ps");
requestPojo.setAction("SFWebServiceInterface");
requestPojo.setUserName(username);
requestPojo.setPassword(password);
List resultList = new ArrayList();
//专利类型为多个需要调用多次
for(Map data : dataList) {
JSONObject result = SOAPWebserviceUtil.callWebService(requestPojo, new JSONObject(data));
resultList.add(result);
}
// String result = restClient.post(url, data);
resultMap.put("result", resultList);
logger.info("调用PLM的返回值为"+resultList);
logger.info("------------结束向PLM系统推送专利申请信息--------------");
return RestResult.data(resultMap);
}
其实主要就是封装一个model 然后调用就可以了,怎么样很简单吧,当时也算是调了一天才调通。。。本文到这里也就结束了,希望大家元旦快乐!