c#调用JAVA的Webservice处理XML数据及批量轮询的实现方法

时间:2023-03-09 07:25:58
c#调用JAVA的Webservice处理XML数据及批量轮询的实现方法

前段时间做一个调用外单位WEBSERVICE的项目,项目完成的功能其实很简单,就是我们单位有很多车友会员,我们想对他们提供车辆违章信息告之服务!我们这边交警部门给我们开放了WS的接口,我们就是想通过这个WS,来轮询会员的违章信息!
       其中那个Webservice使用JAVA的Xfire开发的,当时想像得很简单,因为WS(Webservice)可以跨平台调用,因此非常适合不同系统之间数据交换!网上也有很多调用的代码!但我在实际使用中还是遇到了一些问题!首先是我们要调用的那个WS数据管理非常严格,为了数据的安全,他们在中间加入防火墙,访问是通过VPN来进行的,并且他们对访问端口进行映射,我刚开始通过.net来添加WEB 服务,可以访问到方法名称,但在程序调用时报404错误!咨询了一下开发商,说是他们通过JAVA开发的程序调用没有问题!对于从未接触过JAVA的我来说安装JDK、TOMCAT、MyEclipse,折腾的不亦乐呼!从网上又找了些视频教程看了几天,好在JAVA和C#有点象,据说C#就是微软借鉴了JAVA很多优点!搞出这么一个C#的新语言!使用JAVA调用了一下,确实可以调用成功!至今我也没搞明白,.net为什么调用不成功,我只知道那两个地址的端口不一样,问题也就卡在这块了,但JAVA能调用成功,却不能理解,咨询了一下开发商那边一个很厉害的资深JAVA工程师(没想到居然还是个MM),说是因为两个平台底层的访问原理不同,后来通过我们上一级技术部门的帮助,给了一个解决方案:
       通过本地使用JAVA来调用WS打包成一个代理方法并发布到本地TOMCAT,再通过.net使用request的方法返回结果!基本思路就是这样!
        实现步骤:
       (一)TOMCAT:http://localhost:8080/readvioinfo.jsp 通过在输入不同的参数返回不同的结果!如:http://localhost:8080/readvioinfo.jsp?hphm=京AW342&hpzl=02
       (二)在.net中的代码实现:
实现的方法代码:
public string getXmlStr(string hphmcode)
        {
            string Url = "http://localhost:8080/readvioinfo.jsp";
            string hphm = hphmcode;
            string hpzl = "02";
            //Encoding encoding = Encoding.GetEncoding("utf-8");
            Encoding encoding = Encoding.GetEncoding("GB2312");
             string postData = "hphm=" + hphm + "&hpzl=" + hpzl;
            byte[] data = encoding.GetBytes(postData);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            //发送数据
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = data.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
            //接收返回值
            HttpWebResponse res = (HttpWebResponse)request.GetResponse();
            StreamReader sReader = new StreamReader(res.GetResponseStream(), System.Text.Encoding.UTF8);
            string strBack = sReader.ReadToEnd();
            //Response.Write(strBack);
            sReader.Close();
            res.Close();
            return strBack;
        }
(三)对返回XML格式数据的处理:
JAVA WS返回的结果是XML格式的字符串:如下
<?xml version="1.0" encoding="utf-8"?>
<root>
   <code>1</code>
   <count>2</count>
   <vioInfo>
      <wfdz>建设路700米处</wfdz>
      <wfsj>2010-01-15</wfsj>
      <clbj>未处理</clbj>
      <jkbj>未交款</jkbj>
      <wfnr>机动车行驶超过规定时速30%以上不足50%的</wfnr>
   </vioInfo>
<vioInfo>
      <wfdz>华南路强生中学北300米处</wfdz>
      <wfsj>2009-09-08</wfsj>
      <clbj>未处理</clbj>
      <jkbj>未交款</jkbj>
      <wfnr>机动车行驶超过规定时速30%以上不足50%的</wfnr>
   </vioInfo>
</root>

在.net可以方便的对XML数据进行读取和处理!个人感觉比JAVA要方便啊,JAVA要通过SAX和DOM4J(反正我没研究过)!我是将返回结果放到一个富文本框rtb_result里。
实现代码如下:

string strXML = this.rtb_result.Text.Trim();
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(strXML);
                XmlElement root = doc.DocumentElement;
                XmlNodeList mynodelist = doc.SelectNodes("//root/vioInfo"); //查询全部vioInfo节点  
                 if (mynodelist.Count !=0)
                 {
                //循环遍历节点,查询是否存在该节点  
                       for (int i = 0; i < mynodelist.Count; i++)
                             {
                               this.rtb_result.Text="违章地点:"+mynodelist[i].ChildNodes[0].InnerText + "\n";
                               this.rtb_result.Text+="违章时间:"+mynodelist[i].ChildNodes[1].InnerText + "\n";
                               this.rtb_result.Text +="处理情况:"+ mynodelist[i].ChildNodes[2].InnerText + "\n";
                                this.rtb_result.Text +="交款情况:"+ mynodelist[i].ChildNodes[3].InnerText + "\n";
                                this.rtb_result.Text +="违章内容:"+ mynodelist[i].ChildNodes[4].InnerText + "\n";
                            }
                  }
                 else
                   {
                      this.rtb_result.Text = "无返回的结果集!";
                    }
上面的代码完成将返回的XML数据读取我们需要的节点内容并返回到富文本框上显示出来
(四)怎么实现批量轮询的功能,这也是我们最终要得到的功能!我的设想是让用户通过导入一个记录包括车牌号码、手机号码、车辆类型等会员信息的EXCEL文件,将会员信息导入到数据控件中,再通过逐条读取信息与信息做为上面步骤的查询参数,每次读取将返回的信息追加到窗体的富文本框中,整个循环完成后也就完成了本次会员的违章信息轮询!在读取EXCEL文档我采用了ADO.NET,将EXCEL做为一个数据源来加载的,加载完成后,采用datareader控制来逐条读数据,这样速度比较快!完成的代码如下:
private void btn_getdata_Click(object sender, EventArgs e)
        {
            this.openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "Excel files(*.xls)|*.xls";
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                loadXsl2Reader();
            }
           
        }
public void loadXsl2Reader()
        {
            int lookNum = 0;
            FileInfo fileInfo = new FileInfo(openFileDialog1.FileName);
            string filePath = fileInfo.FullName;
            string connExcel = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties=Excel 8.0";
            try
            {
                OleDbConnection oleDbConnection = new OleDbConnection(connExcel);
                oleDbConnection.Open();
                //获取excel表
                DataTable dataTable = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                //获取sheet名,其中[0][1]...[N]: 按名称排列的表单元素
                string tableName = dataTable.Rows[0][2].ToString().Trim();
                tableName = "[" + tableName.Replace("'", "") + "]";
                //利用SQL语句从Excel文件里获取数据并填充到datareader中
                string query = "SELECT 车牌号码,right(车架号,4) as 验证码,手机号码 FROM " + tableName;
                OleDbCommand usrCMD = oleDbConnection.CreateCommand();
                usrCMD.CommandText = query;
                OleDbDataReader usrd= usrCMD.ExecuteReader();
                this.rtb_result.Text = "车牌号码 手机号 违章地址 违章时间 处理情况 交款情况 违章内容\n";
                //string rtbresult="";
             
                while (usrd.Read())
                {
                  
                    string para_cphm = usrd["车牌号码"].ToString().Trim();
                    string para_code = usrd["验证码"].ToString().Trim();
                    string para_mbphone = usrd["手机号码"].ToString().Trim();
                    string strXML = GetResultXML(para_cphm, para_code).Trim();
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(strXML);
                    XmlElement root = doc.DocumentElement;
                    XmlNodeList mynodelist = doc.SelectNodes("//root/vioInfo"); //查询全部vioInfo节点 
                    if (mynodelist.Count != 0)
                    {
                        //MessageBox.Show("共有" + mynodelist.Count + "条违章记录!");
                        //循环遍历节点,查询是否存在该节点
                        //this.rtb_result.Text = "";
                        for (int i = 0; i < mynodelist.Count; i++)
                        {
                            lookNum += 1;
                            this.label3.Text = "正在匹配ing......:已匹配" + lookNum.ToString() + "条记录!";
                            this.rtb_result.Text += para_cphm+" ";
                            this.rtb_result.Text += para_mbphone + " ";
                            this.rtb_result.Text += mynodelist[i].ChildNodes[0].InnerText+" ";
                            this.rtb_result.Text += Convert.ToDateTime(mynodelist[i].ChildNodes[1].InnerText).ToString("yyyyMMdd-HH:mm")+" ";
/*上句为什么要这么写是为了将DATETIME显示为一个20100801-21:25格式的字符串,方便EXCEL导入文本时不会出现字段错误*/
                            this.rtb_result.Text += mynodelist[i].ChildNodes[2].InnerText +" ";
                            this.rtb_result.Text += mynodelist[i].ChildNodes[3].InnerText + " ";
                            this.rtb_result.Text += mynodelist[i].ChildNodes[4].InnerText + "\n";
                                                      
                            //RichTextBox中的文本自动下滚到最后,使窗体在执行数据轮询时显示滚动数据
                            this.rtb_result.Select(this.rtb_result.TextLength, 0);
                            this.rtb_result.Focus();
                            this.rtb_result.ScrollToCaret();
                        }
                    }
                 
                   
                }
                    usrd.Close();
                    oleDbConnection.Close();
                   
                    MessageBox.Show("轮询结束!共有" + lookNum.ToString() + "条违章记录!请点击保存将查询结果保存为文本文件");
                    this.label3.Text = "共查询到:"+lookNum.ToString()+"条记录!";
            
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
       
        }
(五)导出到文本文件:
private void button5_Click(object sender, EventArgs e)
        {
            if (this.rtb_result.Text != "")
            {
                this.saveFileDialog1.Filter = "txt files(*.txt)|*.txt";
                this.saveFileDialog1.FilterIndex = 2;
                this.saveFileDialog1.RestoreDirectory = true;
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    string filepath = "";
                    string resultStr = this.rtb_result.Text.Replace("\n", "\r\n"); ;
                    filepath = saveFileDialog1.FileName;
                    StreamWriter sTmp = new StreamWriter(filepath);
                    sTmp.WriteLine(resultStr);
                    sTmp.Flush();
                    sTmp.Close();
                    MessageBox.Show("文件已成功导出到" + filepath);
                }
            }
            else
            {
                MessageBox.Show("没有记录!");
            }
       }
导出的文本文件可以通过EXCEL导入进来再编辑、修改、过滤、筛选等操作就比较*了!当然也把代码修改一下直接导出EXCEL也是很方便的!上述的功能还很简单,只是完成了基本功能的实现,程序还是要通过后期的使用不断完善!