我们上一次创建了出口报运的WebService的搭建,测试的时候,我们仅仅得到了WebService给我们回复的soap结构的XML对象,但是我们没有去解析。下面我们来完成soap的XML的解析,并把相应的数据通过javascript安插在table中。
我们先来分析一下之前我们saop发出的XML请求和得到的XML回复的例子
请求:
回复:
我们来分析回复以便于我们来解析:
<soap:Envelope>是头文件不需要解析。可以发现我们需要的信息都是在<return>标签对中放置的,我们要从<return>的子元素中找到我们需要的信息。
具体代码(在上次的基础上):
运行之后的效果:
因为我们是出口报运跟踪,所以我们要添加一个“状态”的显示栏(加在备注下面):
这个时候回馈的里面并没有state状态,原因是因为我们没有设默认值,我们在数据库中给它填写一个“0”(0-草稿,1-已上报,2-装修,3-委托,4-发票,5-财务):
这个时候在js方法中添加以下代码:
此时我们再次点击“查看”,就可以得到出口报运当前的“状态”了:
我们可以注意到,我们的id是写死的,下面我们让用户录入查询的报运号,我们去进行查询:
我们修改html,添加报运编号输入框:
然后js修改:
我们修改的部分是得到input框输入的id值,然后拼接到soap的XML请求中。
我们试验一下,输入之前那个id号,我们得到了相应的出口报运信息:
但是当我们输入一个不存在的id号的时候,是不可以查询出来信息的,我们要检测一下我们的数据是不是已经查到了。
根据soap规则(我们可以用上一次我们的测试用具去测试一个空的id),如果发送的请求中id不存在,我们返回的XML数据中没有<return>标签。所以我们要检测return标签,存不存在,给予用户提示:
然后进行测试:
友好提示也已经完成!
最后一个问题,我们肯定最后不能让用户去输入我们的id(UUID的我们自己都记不住,怎么可能让用户去记,而且会有安全隐患),我们之后可以去新增一个专门用来服务WebService的get方法,我们专门设置一个Mapper去服务它。我们可以使用其他的字段(报运号或信用证号)来查询。
我们先来分析一下之前我们saop发出的XML请求和得到的XML回复的例子
请求:
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://impl.service.jk.hpu.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <q0:get>
- <arg0>39cd8f20-50f8-4bc1-96d5-de6de3d7c8b4</arg0>
- </q0:get>
- </soapenv:Body>
- </soapenv:Envelope>
回复:
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Body>
- <ns2:getResponse xmlns:ns2="http://impl.service.jk.hpu.cn/">
- <return>
- <consignee>南京</consignee>
- <contractIds>392bf3b2-cb0e-4e7a-ba02-c91ce83e9fe1,55743f24-f092-47ac-b149-358785437238</contractIds>
- <customerContract>3 2</customerContract>
- <destinationPort>深圳港</destinationPort>
- <id>39cd8f20-50f8-4bc1-96d5-de6de3d7c8b4</id>
- <inputDate>2015-10-09T00:00:00+08:00</inputDate>
- <lcno>T/T</lcno>
- <marks>11</marks>
- <priceCondition>2</priceCondition>
- <remark>22</remark>
- <shipmentPort>连云港</shipmentPort>
- <transportMode>1</transportMode>
- </return>
- </ns2:getResponse>
- </soap:Body>
- </soap:Envelope>
我们来分析回复以便于我们来解析:
<soap:Envelope>是头文件不需要解析。可以发现我们需要的信息都是在<return>标签对中放置的,我们要从<return>的子元素中找到我们需要的信息。
具体代码(在上次的基础上):
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ include file="../../base.jsp"%>
- <%@ include file="../../baselist.jsp"%>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>出口报运跟踪</title>
- <script language="javascript" src="${ctx}/js/datepicker/WdatePicker.js"></script>
- <script type="text/javascript">
- /*
- 开发步骤
- 1.创建xmlHttpRquest对象
- 2.open('POST',url,true)链接
- 3.设置请求头
- 4.send(xml)
- 5.回调函数,接收响应xml
- 6.从返回的XML抓取我们相关的信息
- */
- var xmlHttpRequest;
- if(window.XMLHttpRequest){
- //针对FireFox、Mozillar、Opera、Safari、IE7、IE8
- xmlHttpRequest=new XMLHttpRequest();
- //修复类似Mozillar浏览器的bug
- if(xmlHttpRequest.overrideMimeType){
- xmlHttpRequest.overrideMimeType("text/xml");
- }
- }else if(window.ActiveXObject){
- //所有的IE中window.ActiveXObject条件都成立
- //针对IE6、IE5.5、IE5(现在没人用了,可以把这条if分支删除)
- //两个可以用于创建XMLHttpRequest对象的控件名称,保存在一个js的数组中
- //排在前面的版本最新
- var activeName=["MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
- for(var i=0;i<activeName.length;i++){
- try{
- //获取一个控件名进行创建,如果创建成功就终止循环
- //如果创建失败,会抛出异常,然后就可以继续循环,继续尝试创建
- xmlHttpRequest=new ActiveXObject(activeName[i]);
- break;
- }catch(e){
- //仍然不能创建,抛出异常后,给出友好提示
- }
- }
- }
- //发送soap请求
- function sendMsg(){
- var url="http://localhost/jx-Maven-Webapp/cxf/ExportServiceImpl";//WebService请求路径
- var reuqestBody="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
- +"xmlns:q0=\"http://impl.service.jk.hpu.cn/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
- +"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
- +"<soapenv:Body><q0:get> <arg0>"
- +"39cd8f20-50f8-4bc1-96d5-de6de3d7c8b4"
- +"</arg0> </q0:get></soapenv:Body></soapenv:Envelope>";
- xmlHttpRequest.open("POST",url,true);//打开链接
- xmlHttpRequest.setRequestHeader("Content-Type","text/xml;charset=utf-8");//设置请求头
- xmlHttpRequest.send(reuqestBody);//发送soap请求
- xmlHttpRequest.onreadystatechange=_back;//在onreadystatechange事件上设置回调函数
- }
- //回调函数
- function _back(){
- if(xmlHttpRequest.readyState==4){//提交完成后
- if(xmlHttpRequest.status==200){
- var rerXml=xmlHttpRequest.responseXML;
- var ret=rerXml.getElementsByTagName("return")[0];//获取return节点
- //获取报运号
- var customContract=ret.getElementsByTagName("customerContract");
- var textNode=customContract[0].firstChild;
- document.getElementById("customContract").innerHTML=textNode.nodeValue;
- //获取制单日期
- var inputDate=ret.getElementsByTagName("inputDate");
- textNode=inputDate[0].firstChild;
- document.getElementById("inputDate").innerHTML=textNode.nodeValue;
- //获取信用证号
- var lcno=ret.getElementsByTagName("lcno");
- textNode=lcno[0].firstChild;
- document.getElementById("lcno").innerHTML=textNode.nodeValue;
- //获取收货人及地址
- var consignee=ret.getElementsByTagName("consignee");
- var textNode=consignee[0].firstChild;
- document.getElementById("consignee").innerHTML=textNode.nodeValue;
- //获取装运港
- var shipmentPort=ret.getElementsByTagName("shipmentPort");
- var textNode=shipmentPort[0].firstChild;
- document.getElementById("shipmentPort").innerHTML=textNode.nodeValue;
- //获取目的港
- var destinationPort=ret.getElementsByTagName("destinationPort");
- var textNode=destinationPort[0].firstChild;
- document.getElementById("destinationPort").innerHTML=textNode.nodeValue;
- //获取价格条件
- var priceCondition=ret.getElementsByTagName("priceCondition");
- var textNode=priceCondition[0].firstChild;
- document.getElementById("priceCondition").innerHTML=textNode.nodeValue;
- //获取运输方式
- var transportMode=ret.getElementsByTagName("transportMode");
- var textNode=transportMode[0].firstChild;
- document.getElementById("transportMode").innerHTML=textNode.nodeValue;
- //获取唛头
- var marks=ret.getElementsByTagName("marks");
- var textNode=marks[0].firstChild;
- document.getElementById("marks").innerHTML=textNode.nodeValue;
- //获取备注
- var remark=ret.getElementsByTagName("remark");
- var textNode=remark[0].firstChild;
- document.getElementById("remark").innerHTML=textNode.nodeValue;
- //获取备注
- var state=ret.getElementsByTagName("state");
- var textNode=state[0].firstChild;
- document.getElementById("state").innerHTML=textNode.nodeValue;
- }else{
- alert("访问失败!");
- }
- }
- }
- </script>
- </head>
- <body>
- <form method="post">
- <div id="menubar">
- <div id="middleMenubar">
- <div id="innerMenubar">
- <div id="navMenubar">
- <ul>
- <li id="save"><a href="#" onclick="sendMsg();">查看</a></li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="textbox" id="centerTextbox">
- <div class="textbox-header">
- <div class="textbox-inner-header">
- <div class="textbox-title">
- 出口报运跟踪
- </div>
- </div>
- </div>
- <div>
- <div>
- <table class="commonTable" cellspacing="1">
- <tr>
- <td class="columnTitle_mustbe">合同或确认书号:</td>
- <td class="tableContent" id="customContract"></td>
- <td class="columnTitle_mustbe">制单日期:</td>
- <td class="tableContent" id="inputDate">
- </td>
- </tr>
- <tr>
- <td class="columnTitle_mustbe">信用证号:</td>
- <td class="tableContent" id="lcno"></td>
- <td class="columnTitle_mustbe">收货人及地址:</td>
- <td class="tableContent" id="consignee"></td>
- </tr>
- <tr>
- <td class="columnTitle_mustbe">装运港:</td>
- <td class="tableContent" id="shipmentPort"></td>
- <td class="columnTitle_mustbe">目的港:</td>
- <td class="tableContent" id="destinationPort"></td>
- </tr>
- <tr>
- <td class="columnTitle_mustbe">价格条件:</td>
- <td class="tableContent" id="priceCondition">
- </td>
- <td class="columnTitle_mustbe">运输方式:</td>
- <td class="tableContent" id="transportMode">
- </td>
- </tr>
- <tr>
- <td class="columnTitle_mustbe">唛头:</td>
- <td class="tableContent" id="marks"></td>
- <td class="columnTitle_mustbe">备注:</td>
- <td class="tableContent" id="remark"></td>
- </tr>
- </table>
- </div>
- </div>
- </form>
- </body>
- </html>
运行之后的效果:
因为我们是出口报运跟踪,所以我们要添加一个“状态”的显示栏(加在备注下面):
- <tr>
- <td class="columnTitle_mustbe">状态:</td>
- <td class="tableContent" id="state"></td>
- </tr>
这个时候回馈的里面并没有state状态,原因是因为我们没有设默认值,我们在数据库中给它填写一个“0”(0-草稿,1-已上报,2-装修,3-委托,4-发票,5-财务):
这个时候在js方法中添加以下代码:
- //获取状态
- var state=ret.getElementsByTagName("state");
- var textNode=state[0].firstChild;
- var s="";
- if(textNode.nodeValue=='1'){
- s="已上报,待装箱";
- }else if(textNode.nodeValue=='2'){
- <span style="white-space:pre"> </span>s="已装箱,待委托";
- }else if(textNode.nodeValue=='3'){
- s="已委托,待发票通知";
- }else if(textNode.nodeValue=='4'){
- s="已发票,流程顺利完成";
- }else if(textNode.nodeValue=='5'){
- s="财务处理";
- }else if(textNode.nodeValue=='0'){
- s="草稿处理状态";
- }
- document.getElementById("state").innerHTML="<font color='red'><b>"+s+"</b></font>";
此时我们再次点击“查看”,就可以得到出口报运当前的“状态”了:
我们可以注意到,我们的id是写死的,下面我们让用户录入查询的报运号,我们去进行查询:
我们修改html,添加报运编号输入框:
- <tr>
- <td class="columnTitle_mustbe">报运编号:</td>
- <td class="tableContent"><input type="text" name="id" id="id"/></td>
- </tr>
然后js修改:
- //发送soap请求
- function sendMsg(){
- var id=document.getElementById("id").value;//用户输入的条件
- var url="http://localhost/jx-Maven-Webapp/cxf/ExportServiceImpl";//WebService请求路径
- var reuqestBody="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
- +"xmlns:q0=\"http://impl.service.jk.hpu.cn/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
- +"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
- +"<soapenv:Body><q0:get> <arg0>"
- +id
- +"</arg0> </q0:get></soapenv:Body></soapenv:Envelope>";
- xmlHttpRequest.open("POST",url,true);//打开链接
- xmlHttpRequest.setRequestHeader("Content-Type","text/xml;charset=utf-8");//设置请求头
- xmlHttpRequest.send(reuqestBody);//发送soap请求
- xmlHttpRequest.onreadystatechange=_back;//在onreadystatechange事件上设置回调函数
- }
我们修改的部分是得到input框输入的id值,然后拼接到soap的XML请求中。
我们试验一下,输入之前那个id号,我们得到了相应的出口报运信息:
但是当我们输入一个不存在的id号的时候,是不可以查询出来信息的,我们要检测一下我们的数据是不是已经查到了。
根据soap规则(我们可以用上一次我们的测试用具去测试一个空的id),如果发送的请求中id不存在,我们返回的XML数据中没有<return>标签。所以我们要检测return标签,存不存在,给予用户提示:
- //回调函数
- function _back(){
- if(xmlHttpRequest.readyState==4){//提交完成后
- if(xmlHttpRequest.status==200){
- var rerXml=xmlHttpRequest.responseXML;
- var ret=rerXml.getElementsByTagName("return")[0];//获取return节点
- if(ret!=null){
- //获取报运号
- var customContract=ret.getElementsByTagName("customerContract");
- var textNode=customContract[0].firstChild;
- document.getElementById("customContract").innerHTML=textNode.nodeValue;
- //获取制单日期
- var inputDate=ret.getElementsByTagName("inputDate");
- textNode=inputDate[0].firstChild;
- document.getElementById("inputDate").innerHTML=textNode.nodeValue;
- //获取信用证号
- var lcno=ret.getElementsByTagName("lcno");
- textNode=lcno[0].firstChild;
- document.getElementById("lcno").innerHTML=textNode.nodeValue;
- //获取收货人及地址
- var consignee=ret.getElementsByTagName("consignee");
- var textNode=consignee[0].firstChild;
- document.getElementById("consignee").innerHTML=textNode.nodeValue;
- //获取装运港
- var shipmentPort=ret.getElementsByTagName("shipmentPort");
- var textNode=shipmentPort[0].firstChild;
- document.getElementById("shipmentPort").innerHTML=textNode.nodeValue;
- //获取目的港
- var destinationPort=ret.getElementsByTagName("destinationPort");
- var textNode=destinationPort[0].firstChild;
- document.getElementById("destinationPort").innerHTML=textNode.nodeValue;
- //获取价格条件
- var priceCondition=ret.getElementsByTagName("priceCondition");
- var textNode=priceCondition[0].firstChild;
- document.getElementById("priceCondition").innerHTML=textNode.nodeValue;
- //获取运输方式
- var transportMode=ret.getElementsByTagName("transportMode");
- var textNode=transportMode[0].firstChild;
- document.getElementById("transportMode").innerHTML=textNode.nodeValue;
- //获取唛头
- var marks=ret.getElementsByTagName("marks");
- var textNode=marks[0].firstChild;
- document.getElementById("marks").innerHTML=textNode.nodeValue;
- //获取备注
- var remark=ret.getElementsByTagName("remark");
- var textNode=remark[0].firstChild;
- document.getElementById("remark").innerHTML=textNode.nodeValue;
- //获取状态
- var state=ret.getElementsByTagName("state");
- var textNode=state[0].firstChild;
- var s="";
- if(textNode.nodeValue=='1'){
- s="已上报,待装箱";
- }else if(textNode.nodeValue=='2'){
- s="已装箱,待委托";
- }else if(textNode.nodeValue=='3'){
- s="已委托,待发票通知";
- }else if(textNode.nodeValue=='4'){
- s="已发票,流程顺利完成";
- }else if(textNode.nodeValue=='5'){
- s="财务处理";
- }else if(textNode.nodeValue=='0'){
- s="草稿处理状态";
- }
- document.getElementById("state").innerHTML="<font color='red'><b>"+s+"</b></font>";
- }else{
- alert("没有查询到数据!");
- //清空所有数据
- document.getElementById("customContract").innerHTML="";
- document.getElementById("inputDate").innerHTML="";
- document.getElementById("lcno").innerHTML="";
- document.getElementById("consignee").innerHTML="";
- document.getElementById("shipmentPort").innerHTML="";
- document.getElementById("destinationPort").innerHTML="";
- document.getElementById("priceCondition").innerHTML="";
- document.getElementById("transportMode").innerHTML="";
- document.getElementById("marks").innerHTML="";
- document.getElementById("remark").innerHTML="";
- document.getElementById("state").innerHTML="";
- }
- }else{
- alert("访问失败!");
- }
- }
- }
然后进行测试:
友好提示也已经完成!
最后一个问题,我们肯定最后不能让用户去输入我们的id(UUID的我们自己都记不住,怎么可能让用户去记,而且会有安全隐患),我们之后可以去新增一个专门用来服务WebService的get方法,我们专门设置一个Mapper去服务它。我们可以使用其他的字段(报运号或信用证号)来查询。
至此,我们的WebService业务编写完成!