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.首 ...
随机推荐
- 最常用的 Eclipse 快捷键总结
本文是一些最实用.最齐全.最省时间的 Eclipse 快捷键总结,这些快捷键可以让帮助你完成工作中的任何一个操作.欢迎参考. 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间 ...
- 如何仿写thinkphp的S方法?
代码如下: <?php $info=S("name","lizhaoyao"); $name=S("name"); var_dump( ...
- 初次接触GWT,知识点总括
初次接触GWT,知识点概括 前言 本人最近开始研究 GWT(Google Web Toolkit) ,现将个人的一点心得贴出来,希望对刚开始接触 GWT的程序员们有所帮助,也欢迎讨论,共同进步. 先说 ...
- 如何优化cocos2d程序的内存使用和程序大小:第一部分_(转)
译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...
- 廖雪锋笔记1---python变量类型
整型:a/b a//b a%b 浮点型:.2 字符串: "" '' r"" r'' '''...''' r'''...'''' 变量值共享:写时复制 NULL型 ...
- 利用systemtap学习Linux路由代码
http://bbs.chinaunix.net/thread-4090162-1-1.html 一.为什么要这样做读kernel route子系统代码,当我弄懂了数据结构之间的关系以及控制流程后,心 ...
- libpcap使用
libpcap是一个网络数据包捕获函数库,功能非常强大,Linux下著名的tcpdump就是以它为基础的.今天我们利用它来完成一个我们自己的网络嗅探器(sniffer) 首先先介绍一下本次实验的环境: ...
- 首页在linux下的哪个文件夹
/data/mindo/tomcat-live/webapps/ROOT/WEB-INF/templates/default/pages/index.jsp svn检出地址 https://sif ...
- iOS 数据持久化(1):属性列表与对象归档
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- partial局部类
局部类型允许我们将一个类.接口或结构分成好几个部分,分别实现在几个不同的.cs文件中. 局部类型适用于以下情况: (1)类型特别大,不宜放在一个文件中实现. (2)一个类型中的一部分代码为自动化工具生 ...