RPC调用Webservice接口是一种远程调用的方式,通过指定Webservice接口的调用地址、命名空间、调用的方法名调用远程接口获取结果
调用的核心类是 org.apache.axis2.rpc.client.RPCServiceClient
调用的远程接口有返回值用 invokeBlocking 方法,无返回值使用 invokeRobust 方法
本例使用的是invokeBlocking 方法。整个示例具体分为三步
1. 封装接口调用工具类 WebServiceInvokeUtil
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.springframework.stereotype.Component;
import javax.xml.namespace.QName;
/**
* @className: WebServiceInvokeUtil
* @Description:
* @author:
* @date: 2019/10/31 10:33
* @return:
* @version: 1.0
*/
@Component
public class WebServiceInvokeUtil {
/**
*
* @param object 拼装报文传入的实体类
* @param msgNo 是此示例中拼装报文工具类方法中需要传的参数
* @param URL 请求路径
* @param methodName 接口方法名
* @param namepaceURL 命名空间
* @param timeout
* @param ticket 是此示例中拼装报文工具类方法中需要传的参数
* @return
* @throws Exception
*/
public String invoke(Object object , String msgNo, String URL, String methodName, String namepaceURL, long timeout, String ticket) throws Exception {
String rspXmlStr ="";
String reqXmlStr="";
RPCServiceClient sender=null;
try {
EndpointReference targetEPR = new EndpointReference(URL);//指定webservice接口地址
QName qname = new QName(namepaceURL,methodName);//设置命名空间和调用的方法名
sender = new RPCServiceClient();//创建远程调用接口的RPC(RPCServiceClient)对象
Options options = sender.getOptions();
options.setTimeOutInMilliSeconds(timeout);//超时时间20s
options.setTo(targetEPR);//设置接口的调用地址
Class<?>[] types = new Class[]{String.class}; //这是针对返值类型的设置
/*
此处是使用工具类江传入的参数实体转换成请求的XML字符串 reqXmlStr
*/
Object[] param = new Object[]{reqXmlStr};//设置请求的报文
Object[] response1 = sender.invokeBlocking(qname, param, types);
rspXmlStr = (String) response1[0];
} catch (AxisFault e) {
e.printStackTrace();
}
return rspXmlStr;
}
}
2. 封装报文组装工具类 BasicUtils
- 创建两个作为头信息和整个请求信息的实体类
Head类封装头请求报文的头信息
RequestInfo 封装整个请求报文信息
import lombok.Data;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @className: Head
* @Description:
* @author:
* @date: 2019/10/31 9:26
* @return:
* @version: 1.0
*/
@Data
@XmlRootElement
public class Head {
private String MSGNO;//交易代码
private String MSGID;//交易请求流水号
private String REQTIME;//业务发起日期
}
```java
package com.gongchen.springboot.entity;
import lombok.Data;
/**
* @className: RequestInfo
* @Description:
* @author:
* @date: 2019/10/31 9:31
* @return:
* @version: 1.0
*/
@Data
public class RequestInfo<T> {
private Head HEAD;
private T CONTENT;
}
BasicUtil
import cn.hutool.json.XML;
import com.gone.springboot.entity.Head;
import com.gone.springboot.entity.RequestInfo;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @className: BasicUtils
* @Description:
* @author:
* @date: 2019/10/31 9:37
* @return:
* @version: 1.0
*/
public class BasicUtils {
private static String XML_TAG = "<?xml version='1.0' encoding='UTF-8'?>";
/**
* RequestInfo 转 xml
* @param r ResultInfo 基础库实体
* @param clazz data所属实体
* @return
*/
@SuppressWarnings("rawtypes")
public static <T> String getXmlFromRequestInfo(RequestInfo r,Class<T> clazz) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias("ROOT", r.getClass());
xStream.aliasSystemAttribute(null, "class");
return addHeaderByXml(xStream.toXML(r));
}
public static <T> String getXmlFromRequestInfo(RequestInfo r) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias("ROOT", r.getClass());
xStream.aliasSystemAttribute(null, "class");
return addHeaderByXml(xStream.toXML(r));
}
/**
* 添加消息头至xml
* @param xml
* @return
*/
public static String addHeaderByXml(String xml) {
StringBuffer buff=new StringBuffer();
buff.append(XML_TAG);
buff.append("\r\n"+xml);
return buff.toString();
}
/**
* xml to json
* @param xml
* @return
*/
public static String xml2json(String xml) {
return XML.toJSONObject(xml).toString();
}
/**
* 初始化数据中心webservice请求头信息
* @param ticket
* @return
*/
public static Head initHead( String msgNo) {
Head head = new Head();
head.setREQTIME("2019-12-31");
head.setMSGID(getMsgId());
head.setMSGNO(msgNo);//
return head;
}
/**
* @param obj datalist数据,非list
* 创建数据中心webservice请求格式
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static RequestInfo createRequestInfo(Object obj,String msgNo) {
RequestInfo r = new RequestInfo<>();
r.setHEAD(initHead(msgNo));
r.setCONTENT(obj);
return r;
}
/**
* 生成流水号
* @return
*/
private static String getMsgId(){
LocalDateTime date = LocalDateTime.now();
System.out.println("当前日期=" + date);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddhhmmssSSS");
System.out.println(date.format(formatter));
return "36000000"+date.format(formatter);
}
/**
* 拼装需要的xml格式
* @param obj
* @param ticket
* @param msgNo
* @return
*/
public static String getXmlFromObj(Object obj,String ticket,String msgNo){
RequestInfo<?> r = createRequestInfo(obj,msgNo);
String xml = getXmlFromRequestInfo(r);
return xml;
}
}
3. 工具类 WebServiceInvokeUtil合并BasicUtils转换XML报文的部分调用
import com.gone.springboot.entity.RequestInfo;
import com.gone.springboot.utils.BasicUtils;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.springframework.stereotype.Component;
import javax.xml.namespace.QName;
/**
* @className: WebServiceInvokeUtil
* @Description:
* @author:
* @date: 2019/10/31 10:33
* @return:
* @version: 1.0
*/
@Component
public class WebServiceInvokeUtil {
/**
*
* @param object 拼装报文传入的实体类
* @param msgNo 是此示例中拼装报文工具类方法中需要传的参数
* @param URL 请求路径
* @param methodName 接口方法名
* @param namepaceURL 命名空间
* @param timeout
* @param ticket 是此示例中拼装报文工具类方法中需要传的参数
* @return
* @throws Exception
*/
public String invoke(Object object , String msgNo, String URL, String methodName, String namepaceURL, long timeout, String ticket) throws Exception {
String rspXmlStr ="";
String reqXmlStr="";
RPCServiceClient sender=null;
try {
EndpointReference targetEPR = new EndpointReference(URL);//指定webservice接口地址
QName qname = new QName(namepaceURL,methodName);//设置命名空间和调用的方法名
sender = new RPCServiceClient();//创建远程调用接口的RPC(RPCServiceClient)对象
Options options = sender.getOptions();
options.setTimeOutInMilliSeconds(timeout);//超时时间20s
options.setTo(targetEPR);//设置接口的调用地址
Class<?>[] types = new Class[]{String.class}; //这是针对返值类型的设置
/* 此处是使用工具类江传入的参数实体转换成请求的XML字符串 reqXmlStr */
RequestInfo<?> r = BasicUtils.createRequestInfo(object,msgNo);
reqXmlStr = BasicUtils.getXmlFromRequestInfo(r);
Object[] param = new Object[]{reqXmlStr};//设置请求报文
Object[] response1 = sender.invokeBlocking(qname, param, types);
rspXmlStr = (String) response1[0];
} catch (AxisFault e) {
e.printStackTrace();
}
return rspXmlStr;
}
}
---------------------------------------------------------------------------------------------
- BasicUtils中组装XML报文是通过XStream BasicUtils和WebserviceUtils两个类中引入的jar包依赖如下
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>com.springsource.com.thoughtworks.xstream</artifactId>
<version>1.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.6.3</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.6.3</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.6.3</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.6.3</version>
</dependency>
-
在Head类里面的定义的头信息的字段的值在BasicUtils中是需要进行设置的
-
在BasicUtils中还有xml转为JSON的方法,对于我们需要获得JSON对象再转换成实体返回的操作是可以直接使用再进行转换的