SOAP XML发送请求以及 返回的XML解析---webservice

最近项目需要调用外部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单产品C2014-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里面的内容

SOAP XML发送请求以及 返回的XML解析---webservice_第1张图片

 先上获取到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 ,定义一个存list的对象,然后再定义一个T对象,然后通过JAXBContext进行解析:

@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
	

 

 

 

 

 

 

 

 

你可能感兴趣的:(java后端)