ICE学习第四步-----客户端请求服务器返回数据
这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上。
根据上一篇文章介绍的Slice语法,我们先来定义ICE文件。我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法。
结构如下:
定义结构体,和数据库中表的列对应,添加序列(相当于数组类型)。
在获取表的方法中注意要记得#include带有结构的ice文件,并把接口函数的返回值类型写成之前定义的数组类型,否则就像HelloWorld例子中只能在服务器显示,调回不到客户端了。(DbTableDataSeq getDataFromDb(string requestCode);这个方法其实就是客户端一调用,然后服务器操作完成,最后返回DbTableDataSeq类型的数据)
编译ICE文件:
在数据库中随便插入几条数据:
之后是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件,对具有接口函数的ICE文件创建实现类,实现抽象类DoSelectTableDisp_
大体结构如下图:
为了结构能更清晰,我们把它改成这样,同时添加上查询数据库的方法:
给出这几个类的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleSer.common
{
public class DbData
{
public string dataName;//数据库中列名
public object dataValue;//数据库中列值
} public class DbDataList
{
public IList<DbData> dataRow;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common;
using IBM.Data.DB2;
using System.Data; namespace ConsoleSer.database
{
public class Db2:DbMain
{
public override IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>(); using (DB2Connection con = new DB2Connection("server=127.0.0.1;database=TEST;uid=db2admin;pwd=db2admin;"))
{
con.Open();
DB2DataAdapter oda = new DB2DataAdapter(strSql, con);
DataSet ds = new DataSet();
oda.Fill(ds);
if (ds.Tables.Count > )
{
DataTable dt = ds.Tables[];
for (int i = ; i < dt.Rows.Count; i++)
{
IList<DbData> rowsData = new List<DbData>();
for (int j = ; j < dt.Columns.Count; j++)
{
DbData data = new DbData();
data.dataName = dt.Columns[j].ColumnName;
data.dataValue = dt.Rows[i][data.dataName];
rowsData.Add(data);
}
DbDataList rows = new DbDataList();
rows.dataRow = rowsData;
list.Add(rows);
}
}
}
return list;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common; namespace ConsoleSer.database
{
public class DbMain
{
public virtual IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>();
return list;
}
}
}
最终查询完数据库返回的是这样的一条数据:(IList<DbDataList> list = new List<DbDataList>(); DbDataList包含两个字段string dataName;object dataValue;)
但是这并不是我们想要的返回类型,我们再将其转换为DbTableData类型数组,于是在TestTableMethodI实现类中有如下代码(假设客户端请求字符串是getTable):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily;
using ConsoleSer.common;
using ConsoleSer.database; namespace ConsoleSer.slice2csI
{
class TestTableMethodI:DoSelectTableDisp_
{
public static List<DbTableData> tbData = new List<DbTableData>();//数据库中表信息
private static DbMain dbObject = new Db2(); public override DbTableData[] getDataFromDb(string requestCode, Ice.Current current__)
{
if (requestCode == "getTable")
{
Console.WriteLine("收到请求!");
return selectDataFromDb();
}
else
{
throw new Exception();
}
} private DbTableData[] selectDataFromDb()
{
IList<DbDataList> list = dbObject.GetDataFromDatabase("select * from A.T_test"); DbTableData[] objs = new DbTableData[list.Count]; for (int i = ; i < list.Count; i++)
{
DbDataList row = list[i];
DbTableData obj = GetTableObj(row);
tbData.Add(obj);
objs[i] = obj;
}
return objs;
} private DbTableData GetTableObj(DbDataList dataRow)
{
DbTableData obj = new DbTableData();
for (int i = ; i < dataRow.dataRow.Count; i++)
{
DbData data = dataRow.dataRow[i];
setObjValue(data, ref obj);
}
return obj;
} private void setObjValue(DbData data, ref DbTableData obj)
{
string name = data.dataName.ToLower();
switch (name)
{
case "id":
obj.ID = Convert.ToInt32(data.dataValue);
break;
case "nname":
obj.Nname = data.dataValue.ToString();
break;
default:
break;
}
}
}
}
附上Main函数初始化ICE的方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily; namespace ConsoleTestIceServer
{
class Program
{
static void Main(string[] args)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize(ref args);
Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("tableSelector", "default -p 10000");
Ice.Object obj = new ConsoleSer.slice2csI.TestTableMethodI();
adapter.add(obj, Ice.Util.stringToIdentity("tableSelector"));
adapter.activate();
Console.WriteLine("初始化成功!");
ic.waitForShutdown();
}
catch (Exception e)
{
Console.Error.WriteLine(e);
status = ;
}
finally
{
if (ic != null)
{
ic.destroy();
}
}
Environment.Exit(status);
}
}
}
如此一来服务端代码就写好了。
很少用BD2数据库,一直用SqlServer编译时报了如下警告,不能运行:
在网上搜索了一下:改成了.NET Framwork4,没有后面的Client Profile,就可以用了;这个修改需要右击项目,然后选择其中的属性。
接下来我们编写客户端代码:
与服务端相同一开始是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件
大体结构如下图:
在Form上添加三个控件:
给出完整客户端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using tableStructFamily; namespace FormCli
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void btnSendRequestCode_Click(object sender, EventArgs e)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize();
txtShowMsg.AppendText("初始化成功!\r\n");
Ice.ObjectPrx obj = ic.stringToProxy("tableSelector:default -p 10000");
DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
if (selector == null)
{
throw new ApplicationException("Invalid proxy");
}
txtShowMsg.AppendText("开始发送请求!\r\n");
DbTableData[] objs = selector.GetDataFromDb("getTable");
txtShowMsg.AppendText("发送请求成功!\r\n"); if (objs.Length > )
{
txtShowMsg.AppendText("成功获取数据!\r\n");
} foreach (DbTableData td in objs)
{
txtShowMsg.AppendText(td.id.ToString() + "\r\n");
txtShowMsg.AppendText(td.nName.ToString() + "\r\n");
} DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Nname");
foreach (DbTableData td in objs)
{
DataRow dr = dt.NewRow();
dr["ID"] = td.id;
dr["Nname"] = td.nName;
dt.Rows.Add(dr);
} dgvShowTable.DataSource = dt; //显示到gridview中
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
status = ;
}
finally
{
if (ic != null)
ic.destroy();
}
txtShowMsg.AppendText(status.ToString());
//Environment.Exit(status);
} }
}
DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
DbTableData[] objs = selector.GetDataFromDb("getTable");
这两行代码是客户端能获取服务器上数据的关键,客户端与服务器调用相同的函数,通过返回值类型,客户端就能够从服务器上得到返回的数据。
最终运行结果如下:
ICE学习第四步-----客户端请求服务器返回数据的更多相关文章
- Koa2学习(四)POST请求
Koa2学习(四)POST请求 接受请求 POST请求的数据实体,会根据数据量的大小进行分包传送. 当node.js后台收到post请求时,会以buffer的形式将数据缓存起来.Koa2中通过ctx. ...
- C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误
FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址."的错误 解决方法是在原代码上增加这句话 reqFTP.UsePassive = f ...
- Postman----模拟服务器返回数据
使用场景:在某些情况下,比如A接口还没开发好,我们需要测试B接口,刚好B接口的请求数据中需要包含A接口返回的数据,这时我们就可以模拟A接口服务器返回的数据来测试B接口 解决办法: 举例:模拟此 htt ...
- 02 - Unit01:服务器返回数据的json处理+搭建项目环境
服务器返回数据的json处理+搭建项目环境 服务器返回数据的json处理 springMVC JSP响应流程 请求 -->DispatcherServlet -->HandlerMappi ...
- js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可)
js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可) 一.总结 ajax读取json和读取普通文本,和获 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- charles技能之修改请求参数/返回数据(map Local、Rewrite、Breakpoints)
之前一直用postman调接口比较多,但有时候想要去修改APP的页面展示,造数据又会比较麻烦,此时可以用以下三种方法修改请求参数或修改响应: map Local(本地映射).Breakpoints(打 ...
- ICE学习第三步-----Slice语言
ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器 ...
- MongoDB学习(四)客户端工具备份数据库
在上一篇MongoDB学习(三)中讲解了如何在服务器端进行数据的导入导出与备份恢复,本篇介绍下如何利用客户端工具来进行远程服务器的数据备份到本地. 以客户端工具MongoVUE为例来进行讲解: 1.首 ...
随机推荐
- Java数据库编程
ava与数据库交互的主要API是jdbc.jdbc的主要目的是: 1.通过使用SQL或者专有的SQL扩展,程序员可以利用java语言开发访问数据的应用. 2.数据库开发商或者数据库工具开发商改进数据库 ...
- ACM1877_又一版A+B
.这道题与2031极为相似. #include<iostream> using namespace std; void fun(int n,int r) { ]="0123456 ...
- Shtirlits - SGU 125(搜索)
题目大意:B[i, j]表示周围有多少个比它大的数,能否用B数组构造出一个A数组,如果不能输出“NO SOLUTION”. 分析:数据规模比较小,可以直接暴力枚举每个点的值. 代码如下: #inclu ...
- Java做界面的感想。。
我用Swing做出的例子: JavaFX做出的界面: 后来又做出了自己编写的一套基于Synth的L&F,其与直接在代码中重绘某个组件不同,最大优点是具有可插拔性,即在不改变原有程序代码的情况下 ...
- 黑马程序员_<<GUI(图形用户管理)-----2>>
--------------------ASP.Net+Android+IOS开发..Net培训.期待与您交流! -------------------- 8.对话框 对列出目录内容增加了对话框提示, ...
- C# Excel操作类
/// 常用工具类——Excel操作类 /// <para> ------------------------------------------------</para> / ...
- 几个命令行命令的总结(node, babel-cli, babel-node)
node: 输入node, 进入repl环境之后,可以直接运行javascsript表达式,模拟node输出 sh-it-nb0023:static xialei$ node > console ...
- ecshop获取客户端操作系统
<?php /** * 获得客户端的操作系统 * * @access private * @return void */ function get_os() { if (empty($_SERV ...
- HTML5简易在线画图工具
继上次学习了HTML5的路径画圆做了动态时钟.异次元空间的反转做了运动的太阳系,这两天将画线.画圆.填充等知识点结合起来做了一个简易的在线画图工具: 查看DEMO:HTML5简易在线画图工具 功能包括 ...
- hibernate官方新手教程 (转载)
hibernate官方新手教程第一部分 - 第一个Hibernate程序 首先我们将创建一个简单的控制台(console-based)Hibernate程序.我们使用内置数据库(in-memory d ...