打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
WebServicesoap报文请求与响应报文解析

需求

        今日公司要做一个协同办公系统(OA),PC端已经完成。现在要做一个手机端网页端的。从登陆入手,需要向 服务端发送一段请求报文获取响应报文,对响应报文进行解析判断是否登录成功。

       当然手机客户端发送请求就不说了,就是普通的web请求。以下重点来讲怎么发送Soap请求报文来获取响应报文你该进行解析。话说多不如上代码。代码中有必要的注释。


资料

        这是接口信息,描述了输入输出参数特征

  

 

                   这是需要发送的请求报文和服务地址,还有需要我们接收的响应报文。


当然,http://localhost:8080/v6sp2/WorkflowCommonService?xsd=1这个服务地址前部分是自己项目的地址,是要变得。

这就是所有资料信息。

解决方案

        思路:用HttpClinet 来获取响应报文,document文档解析响应报文

       为了结构明确,层次分明,我将冗长的方法封装在了多个方法中,在主方法中体现功能调用顺序,这样思路更清晰些。大家可以看主方法的中的调用顺序进行学习。调用方法出用红色字体标注.思路由黄色底色标注。

  1. public static void main(String[] args) {
  2. StringBuilder soap=new StringBuilder(); //构造请求报文
  3. soap.append(" <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" ");
  4. soap.append(" xmlns:wor=\"http://www.horizon.com/workflow/webservice/client/workflowCommon\">");
  5. soap.append(" <soapenv:Header>");
  6. soap.append(" <HZWFService xmlns=\"http://www.huizhengtech.com/webservice/workflow\"");
  7. soap.append(" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"");
  8. soap.append(" SOAP-ENV:actor=\"http://www.w3.org/2003/05/soap-envelope/role/next\">admin&admin</HZWFService>");
  9. soap.append(" </soapenv:Header>");
  10. soap.append(" <soapenv:Body>");
  11. soap.append(" <wor:sysLogin>");
  12. soap.append(" <loginName>loginname</loginName >");
  13. soap.append(" <password>password</password>");
  14. soap.append(" <dbidentifier>system</dbidentifier>");
  15. soap.append(" </wor:sysLogin>");
  16. soap.append(" </soapenv:Body>");
  17. soap.append(" </soapenv:Envelope>");
  18. String requestSoap=soap.toString();
  19. String serviceAddress="http://IP:Port/WorkflowCommonService?wsdl"; //服务地址(将XXXX替换成自己项目的地址)
  20. String charSet="utf-8";
  21. String contentType="text/xml; charset=utf-8";
  22. <span style="font-size:24px;">//第一步:调用方法getResponseSoap。返回响应报文和状态码</span>
  23.   Map<String,Object> responseSoapMap=SoapUtil.getResponseSoap(requestSoap, serviceAddress, charSet, contentType);
  24. Integer statusCode=(Integer)responseSoapMap.get("statusCode");
  25. if(statusCode==200){
  26. String responseSoap=(String)responseSoapMap.get("responseSoap");
  27.   String targetNodeName="isSuccess";
  28. <span style="font-size:24px;"> //第二步:调用strXmlToDocument方法。
  29. 将字符串类型的XML的响应报文 转化成Docunent结构文档</span>
  30. Document doc=XMLUtil.strXmlToDocument(responseSoap);
  31. <span style="font-size:24px;"> //第三步:调用getValueByElementName方法。递归获得目标节点的值</span>
  32.   String result= XMLUtil.getValueByElementName(doc,targetNodeName);
  33. if(!StringUtils.isEmpty(result)){
  34. System.out.println(result);
  35.  }
  36. else{
  37. System.out.println("没有此节点或者没有值!");}
  38.   }
  39. else{
  40.   System.out.println("请求失败!");
  41. }
  42. }
 
 
 

工具类    SoapUtil.class  。 

        

  1. /**
  2. * <p>Description: 根据请求报文,请求服务地址获取 响应报文
  3. * @param requestSoap 请求报文
  4. * @param serviceAddress 响应报文
  5. * @param charSet 字符集
  6. * @param contentType 类型
  7. * @return map封装的 服务器响应参数和返回报文.PS:statusCode :200正常响应。responseSoap:响应报文
  8. * <p>thinking: </p>
  9. *
  10. * @author huoge
  11. *</span>
  12. public static Map<String,Object> responseSoap(String requestSoap,String serviceAddress,String charSet, String contentType){
  13. String responseSoap="";
  14. Map<String,Object> resultmap=new HashMap<String,Object>();
  15. PostMethod postMethod = new PostMethod(serviceAddress);
  16. byte[] b = new byte[0];
  17. try {
  18. b = requestSoap.getBytes(charSet);
  19. } catch (UnsupportedEncodingException e) {
  20. e.printStackTrace();
  21. }
  22. InputStream is = new ByteArrayInputStream(b, 0, b.length);
  23. RequestEntity re = new InputStreamRequestEntity(is, b.length, contentType);
  24. postMethod.setRequestEntity(re);
  25. HttpClient httpClient = new HttpClient();
  26. int statusCode = 0;
  27. try {
  28. statusCode = httpClient.executeMethod(postMethod);
  29. resultmap.put("statusCode", statusCode);
  30. } catch (IOException e) {
  31. throw new RuntimeException("执行http请求失败", e);
  32. }
  33. if (statusCode == 200) {
  34. try {
  35. responseSoap = postMethod.getResponseBodyAsString();
  36. resultmap.put("responseSoap", responseSoap);
  37. } catch (IOException e) {
  38. throw new RuntimeException("获取请求返回报文失败", e);
  39. }
  40. } else {
  41. throw new RuntimeException("请求失败:" + statusCode);
  42. }
  43. return resultmap;
  44. }

工具类   XMLUtil.class

     

  1.   /**
  2.     * <p>Description:将字符串类型的XML 转化成Docunent文档结构</p>
  3.      * @param parseStrXml 待转换的xml 字符串
  4.      * @return Document
  5.      *
  6.      * @author  huoge
  7.      */
  8. public static Document strXmlToDocument(String parseStrXml){
  9. StringReader read = new StringReader(parseStrXml);
  10. //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
  11. InputSource source = new InputSource(read);
  12. //创建一个新的SAXBuilder
  13. SAXBuilder sb = new SAXBuilder(); // 新建立构造器
  14. Document doc = null;
  15. try {
  16. doc = sb.build(source);
  17. } catch (JDOMException e) {
  18. e.printStackTrace();
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. return doc;
  23. }
  1. /**
  2. * <p>Description: 根据目标节点名获取值</p>
  3. * @param doc 文档结构
  4. * @param finalNodeName 最终节点名
  5. * @return
  6. *
  7. * @author huoge
  8. */
  9. public static String getValueByElementName(Document doc,String finalNodeName){
  10. Element root = doc.getRootElement();
  11. HashMap<String,Object> map=new HashMap<String,Object>();
  12. <span style="font-size:24px;"> //调用getChildAllText方法。获取目标子节点的值 </span>
  13. Map<String,Object> resultmap=getChildAllText(doc, root,map);
  14. String result=(String)resultmap.get(finalNodeName);
  15. return result;
  16. }
  1. /**
  2. * <p>Description: 递归获得子节点的值</p>
  3. * @param doc 文档结构
  4. * @param e 节点元素
  5. * @param resultmap 递归将值压入map中
  6. * @return
  7. *
  8. * @author huoge
  9. */
  10. public static Map<String ,Object> getChildAllText(Document doc, Element e,HashMap<String,Object> resultmap)
  11. {
  12. if (e != null)
  13. {
  14. if (e.getChildren() != null) //如果存在子节点
  15. {
  16. List<Element> list = e.getChildren();
  17. for (Element el : list) //循环输出
  18. {
  19. if(el.getChildren().size() > 0) //如果子节点还存在子节点,则递归获取
  20. {
  21. getChildAllText(doc, el,resultmap);
  22. }
  23. else
  24. {
  25. resultmap.put(el.getName(), el.getTextTrim()); //将叶子节点值压入map
  26. }
  27. }
  28. }
  29. }
  30. return resultmap;
  31. }

这就是用webservice进行soap接口调用的思路。另外webservice接口调用还可以返回json数据格式然后进行对JSon进行解析,比较容易。

如果对xml文档解析存在疑点,下篇文章我将带大家学习几种XML解析方法。

扩展

     对webservice soap请求,可以借助一个功能强大的软件SoapUI进行测试。也是为了防止中途错误不迷途知返。

打开界面是这样的


点击左上角的soap,会弹出弹框让你写入你的项目名(随便起)和服务地址。


如果地址正确的话,会出现这样的列表,选中一个双击点开是这样的:


左右的输入框的请求报文中?是需要传入的参数,直接填入即可,然后点击左上角绿色三角会得到响应报文。是这样的:

我相信这个工具会很有帮助的,当然他的功能远不止这些。。。

祝大家学习工作愉快!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
关于Webservice接口对接相关总结
解决webservice 异步调用在有的pc客户端是好的,但是在有的pc客户端上用就不行的...
Java 使用httpclient Post与cxf 发布的Webservice通信
Qt实现访问WebService
使用SoapUI 测试Web Service
在Delphi中动态调用webservice
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服