最近项目需要调用外部webservice接口,之前没接触过,研究了2天做个笔记:
1、首先发送请求,格式接口那边已经提供了,期间遇到的问题就是提示“no SOAPAction header” 的错误,请求代码如下:
/**
* 根据参数拼接后发生soap请求
* @param params
* @return
* @throws Exception
*/
public static String SoapRequest(Map params)throws Exception{
String sendMsg = "";
String resultStr = "";
String url = MapUtil.getStrValue(params,"url");
if(StringUtil.isEmpty(url)){
return "";
}
//定义HttpClient
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod(url);
try {
Map reqMap = new HashMap<>();
reqMap.put("reqCode",MapUtil.getStrValue(params,"reqCode"));
reqMap.put("offerId",MapUtil.getStrValue(params,"offerId"));
reqMap.put("srvModule",MapUtil.getStrValue(params,"srvModule"));
//这里是项目写了个工具类拼接请求xml报文
sendMsg = XmlConverterUtil.createXmlFromTemplate(reqMap);
// 然后把Soap请求数据添加到PostMethod中
RequestEntity requestEntity = new StringRequestEntity(sendMsg, "text/xml", "UTF-8");
//设置请求头部,否则可能会报 “no SOAPAction header” 的错误
postMethod.setRequestHeader("SOAPAction","");
postMethod.setRequestHeader("Content-Types","text/xml");
// 设置请求体
postMethod.setRequestEntity(requestEntity);
int status = client.executeMethod(postMethod);
// 打印请求状态码
System.out.println("status:" + status);
// 获取响应体输入流
BufferedReader in = new BufferedReader(
new InputStreamReader(postMethod.getResponseBodyAsStream(),"UTF-8"));
resultStr = IOUtils.toString(in);
// 获取请求结果字符串并转换格式,这里一开始有遇到字符转换问题,后面方法可以解决,可
//以不使用
/*resultStr = resultStr.replaceAll("&", "&");
resultStr = resultStr.replaceAll("<", "<").replaceAll(">", ">");
resultStr = resultStr.replaceAll(""", "\"");
resultStr = (String) XmlConverterUtil.decodeStr(resultStr);*/
}catch (Exception e){
e.printStackTrace();
}
return resultStr;
}
2、根据返回的xml报文解析,转成java对象,先看下返回的格式:
200000573 产品发展类-乐享4G单产品C 2014-05-04 10:24:24.0 销售品类型 in 乐享4G套餐 当前销售品类型 必须订购 100000038 天翼-首返 200000639 集约化_金昌_4G_19-999元天翼产品 2014-05-11 17:31:09.0 零费用周期性事件生成 当前销售品类型 必须订购 100000038 天翼-首返
0
query
CommissionOrderQuery
上面的报文可以分成两部分,一部分是soap的返回头参数,中间content中的是结果xml,我们主要是要将content里面的内容转成java对象集合,先看下content里面的内容
先上获取到content这部分xml内容的代码:
/**
*
* @param soapXml 请求结果string
* @param c 要转换成的java对象
* @param
* @return
*/
public static T soapXmlToBean(String soapXml,Class c){
Iterator iterator = null;
T t = null;
try {
//javax.xml.soap类MessageFactory
MessageFactory msgFactory = MessageFactory.newInstance();
//创建一个soapmessage对象
SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(),
new ByteArrayInputStream(soapXml.getBytes("UTF-8")));
reqMsg.saveChanges();
//取出soapBoby对象
SOAPBody body = reqMsg.getSOAPBody();
遍历子节点
iterator = body.getChildElements();
}catch (Exception e){
e.printStackTrace();
}
while (iterator.hasNext()) {
SOAPElement element = iterator.next();
logger.info("节点名称---:"+element.getNodeName());
if("multiRef".equals(element.getNodeName())){
Iterator it = element.getChildElements();
SOAPElement el = null;
while (it.hasNext()) {
el = it.next();
//取到content子节点的值
if ("content".equals(el.getNodeName())) {
logger.info("子节点值---:"+el.getValue());
//这里是调用工具来将content中的xml转换成java对象
t = XmlConverterUtil.analyzeXmlToBean(el.getValue(),c);
break;
}
}
break;
}
}
return t;
}
3、将xml转换成java对象集合,利用JAXBContext将xml解析成java对象集合,思路就是把xml当做一个list
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CommissionOrderRespType")//根路径
public class CommissionContentResp extends ArrayList implements Serializable {
private static final long serialVersionUID = 1L;
@XmlElement(name="Alllist")//子节点名称
public List getList(){
return this;
}
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Alllist")//根路径
public class CommissionResp implements Serializable {
private static final long serialVersionUID = 1L;
@XmlElement(name="OfferId")
private String offerId;
@XmlElement(name="OfferName")
private String offerName;//
@XmlElement(name="EffDate")
private String effDate;
@XmlElement(name="PricingSectionName")
private String pricingSectionName;
@XmlElement(name="RefObjectName")
private String refObjectName;
@XmlElement(name="OperatorName")
private String operatorName;
@XmlElement(name="AcctItemTypeId")
private String acctItemTypeId;
@XmlElement(name="name")
private String name;
}
/**
* 解析返回报文,返回对象
* */
public static T analyzeXmlToBean(String xmlStr, Class c){
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xmlStr));
} catch (JAXBException e) {
e.printStackTrace();
}
return t;
}
最后传入content里面的xml内容和CommissionContentResp对象就能解析出结果List
补充:
返回报文含有集合加单个对象,可以这样定义:
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ShareMsgQueryRespType")
public class ShareMsgResp extends ArrayList implements Serializable {
private static final long serialVersionUID = 1L;
//private List newlist;
@XmlElement(name="Newlist")
private List newlist;
@XmlElement(name="Alllist")
private ShareContent alllist;
}
返回参数:
602040
其它补退费
611162
天翼大流量套餐功能费
900000001
移动电话
108021
来电显示 (移动业务)
5.00000