大家好,又见面了,我是你们的朋友全栈君。
目录
最近在项目中,在与其他公司做对接中需要回调一个对方的接口,根据对方提供的接口地址,
发现是webservice的接口,而且接口后缀名为.asmx,因为现在webservice接口基本上都是wsdl这种形式,所以使用wsdl调用方式不能用,得使用其他方法。
WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互。 其实WebService并不是什么神秘的东西,它就是一个可以远程调用的类,或者说是组件,把你本地的功能开放出去供别人调用。
下面通过一个示例说明如何在SpringBoot中调用.asmx后缀的webservice接口。
【a】加入pom.xml的依赖
<!--WebService接口依赖-->
<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>org.apache.axis</groupId>
<artifactId>axis-saaj</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.2</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
【b】定义WebService客户端参数字段类
package com.ly.cloud.common.webservice;
/**
* @Description: WebService客户端参数字段类
* @author: weishihuai
* @Date: 2020/6/20 14:40
*/
public class ClientField {
/**
* 参数名称
*/
private String paramName;
/**
* 参数类型
*/
private Class<?> paramType;
/**
* 参数值
*/
private Object paramValue;
public ClientField() {
super();
}
public ClientField(String paramName, Class<?> paramType, Object paramValue) {
super();
this.paramName = paramName;
this.paramType = paramType;
this.paramValue = paramValue;
}
public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public Class<?> getParamType() {
return paramType;
}
public void setParamType(Class<?> paramType) {
this.paramType = paramType;
}
public Object getParamValue() {
return paramValue;
}
public void setParamVaule(Object paramValue) {
this.paramValue = paramValue;
}
}
【c】定义WebService客户端实体类
package com.ly.cloud.common.webservice;
import java.util.List;
/**
* @Description: WebService客户端实体类
* @author: weishihuai
* @Date: 2020/6/20 14:39
*/
public class ClientBean {
/**
* WebService接口请求地址
*/
private String endpointUrl;
/**
* WebService接口请求的命名空间
*/
private String targetNamespace;
/**
* WebService接口请求actionUrl
*/
private String actionUrl;
/**
* WebService接口请求方法名称
*/
private String methodName;
/**
* WebService请求参数集合
*/
private List<ClientField> clientFields;
public ClientBean() {
super();
}
public ClientBean(String endpointUrl, String targetNamespace,
String actionUrl, String methodName, List<ClientField> clientFields) {
super();
this.endpointUrl = endpointUrl;
this.targetNamespace = targetNamespace;
this.actionUrl = actionUrl;
this.methodName = methodName;
this.clientFields = clientFields;
}
public String getEndpointUrl() {
return endpointUrl;
}
public void setEndpointUrl(String endpointUrl) {
this.endpointUrl = endpointUrl;
}
public String getTargetNamespace() {
return targetNamespace;
}
public void setTargetNamespace(String targetNamespace) {
this.targetNamespace = targetNamespace;
}
public String getActionUrl() {
return actionUrl;
}
public void setActionUrl(String actionUrl) {
this.actionUrl = actionUrl;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public List<ClientField> getClientFields() {
return clientFields;
}
public void setClientFields(List<ClientField> clientFields) {
this.clientFields = clientFields;
}
}
【d】创建NHWebServiceUtils.java工具类
package com.ly.cloud.common.webservice;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.encoding.XMLType;
/**
* @description: WebService接口统一调用工具类
* @author: weishihuai
* @mail: weishihuai@ly-sky.com
* @Date: 2020/6/20 14:39
* @version: 1.0
*/
public class NHWebServiceUtils {
/**
* WebService请求发送方法
*
* @param clientBean 客户端请求发送实体类(包含一些请求参数、webservice接口地址等)
* @return 通常返回XML格式的文本
* <p>
* 使用示例:
* List<ClientField> clientFields = new ArrayList<>();
* // 设置请求参数
* ClientField field = new ClientField("strCardno", String.class, xh);
* clientFields.add(field);
* <p>
* ClientBean clientBean = new ClientBean(
* "http://202.192.41.136:8090/Service.asmx",
* "ilasIII OpenAPI", "ilasIII OpenAPI/GetRdrFin",
* "GetRdrFin", clientFields);
* //返回XML
* String returnXml = NHWebServiceUtils.sendWebServiceRequest(clientBean);
*/
public static String sendWebServiceRequest(ClientBean clientBean) {
try {
Object[] paramValues;
//实例化访问对象
Service service = new Service();
//实例化调用对象
Call call = (Call) service.createCall();
//在调用对象中添加WebService地址
call.setTargetEndpointAddress(new java.net.URL(clientBean.getEndpointUrl()));
paramValues = new Object[clientBean.getClientFields().size()];
int i = 0;
//设置入参,第一个参数是命名空间以及参数名,这两个参数是采用一个Qname变量打包传入的,第二个参数是入参的类型(字符或者数字)第三个参数是入参种类
for (ClientField field : clientBean.getClientFields()) {
QName qn = new QName(clientBean.getTargetNamespace(), field.getParamName());
if (field.getParamType() == String.class) {
call.addParameter(qn, XMLType.XSD_STRING, ParameterMode.IN);
} else if (field.getParamType() == int.class) {
call.addParameter(qn, XMLType.XSD_INT, ParameterMode.IN);
} else if (field.getParamType() == Integer.class) {
call.addParameter(qn, XMLType.XSD_INTEGER, ParameterMode.IN);
} else if (field.getParamType() == Double.class) {
call.addParameter(qn, XMLType.XSD_DOUBLE, ParameterMode.IN);
} else if (field.getParamType() == Float.class) {
call.addParameter(qn, XMLType.XSD_FLOAT, ParameterMode.IN);
} else if (field.getParamType() == Long.class) {
call.addParameter(qn, XMLType.XSD_LONG, ParameterMode.IN);
} else {
throw new Exception("请确定传入参数类型是否正确,或者该参数类型还没有被注册。");
}
//获取参数值
paramValues[i] = field.getParamValue();
i++;
}
//设置返回值格式(字符串或者组装对象)
call.setReturnType(XMLType.XSD_STRING);
//是否是SOAPAction这里需要看WebService是否要求如下格式,如果没有要求可以不添加此设置
call.setUseSOAPAction(true);
//如果前面要求是SOAPAction的话需要添加下面设置,指定访问那个命名空间上的那个方法
call.setSOAPActionURI(clientBean.getActionUrl());
//在调用对象中添加WebService对应的命名空间,以及将要调用的函数名
call.setOperationName(new QName(clientBean.getTargetNamespace(), clientBean.getMethodName()));
String ret;
//调用目标方法,设置参数值将返回值转换为String类型
ret = (String) call.invoke(paramValues);
return ret;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
【e】调用示例
package com.ly.cloud.ws2;
import com.ly.cloud.common.webservice.ClientBean;
import com.ly.cloud.common.webservice.ClientField;
import com.ly.cloud.common.webservice.NHWebServiceUtils;
import com.ly.cloud.vo.interfacemng.InterfaceVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.*;
/**
* @description: 图书馆还书WebService接口
* @author: weishihuai
* @date: 2020-06-19 19:59:44
* @version: 1.0
*/
public class LibraryReturnBooksServiceImpl {
private static final Logger logger = LoggerFactory.getLogger(LibraryReturnBooksServiceImpl.class);
/**
* 根据学号远程调用WebService接口查询学生图书馆还书情况
*
* @param xh 学号
* @param params 参数
* @return
*/
@SuppressWarnings("unchecked")
public static InterfaceVO getLxzt(String xh, Map<String, Object> params) {
InterfaceVO resultMsg = new InterfaceVO();
try {
List<ClientField> clientFields = new ArrayList<>();
// 设置参数
ClientField field = new ClientField("strCardno", String.class, xh);
clientFields.add(field);
//图书馆还书
ClientBean clientBean = new ClientBean(
"http://202.192.41.136:8090/Service.asmx",
"ilasIII OpenAPI", "ilasIII OpenAPI/RdrLoanSrch",
"RdrLoanSrch", clientFields);
String returnXml = NHWebServiceUtils.sendWebServiceRequest(clientBean);
logger.error("【图书馆还书】【" + xh + "】WebService接口返回XML: {}", returnXml);
StringBuilder ddString = new StringBuilder("");
if (StringUtils.isNotBlank(returnXml)) {
resultMsg.success();
//解析返回的XML数据
Map<String, String> fieldXmlPaths = new HashMap<>();
fieldXmlPaths.put("Title", "//RdrLoanInfo/Title");
fieldXmlPaths.put("Callno", "//RdrLoanInfo/Callno");
fieldXmlPaths.put("Barcode", "//RdrLoanInfo/Barcode");
fieldXmlPaths.put("Local", "//RdrLoanInfo/Local");
fieldXmlPaths.put("Author", "//RdrLoanInfo/Author");
fieldXmlPaths.put("Loandate", "//RdrLoanInfo/Loandate");
fieldXmlPaths.put("Returndate", "//RdrLoanInfo/Returndate");
List<JSXX> studentBooksList = (List<JSXX>) parserXmlToEntity(returnXml, JSXX.class, fieldXmlPaths);
logger.error("【图书馆还书】【" + xh + "】解析XML为studentBooksList: {}", studentBooksList);
if (CollectionUtils.isNotEmpty(studentBooksList)) {
String bookTitle;
for (JSXX jsxx : studentBooksList) {
bookTitle = jsxx.getTitle();
if (!ddString.toString().contains(bookTitle)) {
ddString.append("《").append(bookTitle).append("》");
}
}
resultMsg.setMessage("未还书籍:" + ddString + "");
resultMsg.setBlzt("0");
logger.info("学生(" + xh + ")}的任务{图书馆还书}未完成!所借书籍{" + studentBooksList.get(0).getTitle() + "}");
} else {
resultMsg.setBlzt("1");
resultMsg.setMessage("没有找到学号为{" + xh + "}的借还书记录!系统默认通过!");
logger.error("没有找到学号为{" + xh + "}的借还书记录!系统默认通过!");
}
} else {
resultMsg.setBlzt("1");
resultMsg.setMessage("没有找到学号为{" + xh + "}的借还书记录!系统默认通过!");
logger.error("没有找到学号为{" + xh + "}的借还书记录!系统默认通过!");
}
resultMsg.setBlts(StringUtils.isNotBlank(ddString.toString()) ? "未还书籍:" + ddString + "" : "请求成功");
} catch (Exception e) {
resultMsg.failed();
resultMsg.setBlts("请求出错,请与管理员联系! ");
resultMsg.setMessage(e.getMessage());
e.printStackTrace();
}
return resultMsg;
}
/**
* 解析XML文本映射到实体类
*
* @param returnXml XML文本
* @param cls 解析生成后映射的Class类对象
* @param fieldXmlPaths XMLPaths集合(XML中的标签路径) 如:
* @return
* @throws DocumentException
*/
public static List<?> parserXmlToEntity(String returnXml, Class cls, Map<String, String> fieldXmlPaths) throws DocumentException {
Document document;
document = DocumentHelper.parseText(returnXml);
try {
//单独用来存属性
List<String> filedNames = new ArrayList<>();
//存放<属性,values>
Map<String, List<Node>> map = new HashMap<>();
if (fieldXmlPaths != null && fieldXmlPaths.size() > 0) {
Iterator it = fieldXmlPaths.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
List<Node> nodes = document.selectNodes(value.toString());
List<Node> list = new ArrayList<>();
for (Node node : nodes) {
list.add(node);
}
//循环放入属性-> 对应的节点
map.put(key.toString(), list);
filedNames.add(key.toString());
}
}
List list = new ArrayList();
//循环将节点的值放入到对象中,然后放入到list
for (int i = 0; i < map.get(filedNames.get(0)).size(); i++) {
Object instance = cls.newInstance();
for (String fieldName : filedNames) {
String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Method method = cls.getMethod(methodName, String.class);
method.invoke(instance, map.get(fieldName).get(i).getText());
}
list.add(instance);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
InterfaceVO interfaceVO = getLxzt("1607300009", null);
System.out.println(interfaceVO);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
/**
* 借书信息类
*/
class JSXX {
private String Title;
private String Callno;
private String Barcode;
private String Local;
private String Author;
private String Loandate;
private String Returndate;
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getCallno() {
return Callno;
}
public void setCallno(String callno) {
Callno = callno;
}
public String getBarcode() {
return Barcode;
}
public void setBarcode(String barcode) {
Barcode = barcode;
}
public String getLocal() {
return Local;
}
public void setLocal(String local) {
Local = local;
}
public String getAuthor() {
return Author;
}
public void setAuthor(String author) {
Author = author;
}
public String getLoandate() {
return Loandate;
}
public void setLoandate(String loandate) {
Loandate = loandate;
}
public String getReturndate() {
return Returndate;
}
public void setReturndate(String returndate) {
Returndate = returndate;
}
@Override
public String toString() {
return "JSXX{" +
"Title='" + Title + '\'' +
", Callno='" + Callno + '\'' +
", Barcode='" + Barcode + '\'' +
", Local='" + Local + '\'' +
", Author='" + Author + '\'' +
", Loandate='" + Loandate + '\'' +
", Returndate='" + Returndate + '\'' +
'}';
}
}
【f】启动main方法进行测试
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
InterfaceVO interfaceVO = getLxzt("1607300009", null);
System.out.println(interfaceVO);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
运行结果:
可见,调用webservice远程接口成功。
小总结:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/134622.html原文链接:https://javaforall.cn