5. 日程安排服务 J2EE 的 .NET 客户端
5.1. 一个 C# 2008 客户端
我们现在假设前面的 Web 服务已可用且处于活动状态。Web 服务可供使用不同语言编写的客户端使用。在此,我们将编写一个 C# 控制台客户端来显示医生列表。
![]() |
首先创建 C# 项目:
![]() |
创建一个名为 [1] 的控制台应用程序 [ListeDesMedecins] [2]。 在 [3] 中,我们为一个 Web 服务创建引用。该工具与 NetBeans 中使用的类似:它会为远程 Web 服务创建一个本地代理。
![]() |
- 在 [1] 中,需指定 Web 服务的 WSDL 文件的 URI(参见第 4.10.2 节)。
- 在 [2] 中,要求向导发现该 URI 所暴露的 Web 服务
- 在 [3] 中,列出已找到的 Web 服务;在 [4] 中,列出该服务暴露的方法。
- 在 [5] 中,指定代理 C 的类应在哪个命名空间中生成
- 在 [6] 中,生成 C 语言代理。
![]() |
- 在 [1] 中,显示了我们刚刚创建的 Web 引用。双击它。
- 在 [2] 中,双击打开的对象浏览器。
- 在 [3] 中,选择命名空间 [ListeDesMedecins.Ws.RdvMedecins],即生成的 C 代理的命名空间。 第一个项 [ListeDesMedecins] 是所创建的 C# 应用程序的默认命名空间(我们将其命名为 ListeDesMedecins)。 第二个名称 [Ws.Rdvmedecins] 是我们在向导中为 C 代理指定的命名空间。最终,C 代理的对象属于命名空间 [ListeDesMedecins.Ws.RdvMedecins]。
- 在 [4] 中,生成的 C 代理对象
![]() |
- 在 [5] 中,[WsDaoJpaClient] 是本地实现远程 Web 服务方法的类。
- 在 [6] 中,包含类 [WsDaoJpaClient] 的方法。其中包含远程 Web 服务的方法,例如 getAllClients 对应 [7]。
让我们来查看生成的实体代码:
![]() |
在上述的 [1] 中,我们请求查看 [client] 类的代码:
...
public partial class client : personne {
}
....
public partial class personne : object, System.ComponentModel.INotifyPropertyChanged {
...
public long id {
...
}
...
}
上文仅保留了本研究所需的代码。
- 第2行:类[client]继承自类[personne],这与Web服务中的情况一致。
- 第 8 行:类 [personne] 的一个公共属性
值得注意的是,生成的代码未遵循 C# 的常规编码规范。类名和公共属性的名称应以大写字母开头。
让我们回到我们的 C# 应用程序:
![]() |
[Program.cs][1] 是测试类。其代码如下:
using System;
using ListeDesMedecins.Ws.RdvMedecins;
using Client = ListeDesMedecins.Ws.RdvMedecins.client;
namespace ListeDesMedecins {
class Program {
static void Main(string[] args) {
try {
// 客户端 [dao] 层的实例化
WsDaoJpaClient dao = new WsDaoJpaClient();
// 医生列表
foreach (Client client in dao.getAllClients()) {
Console.WriteLine(String.Format("{0} {1} {2}", client.titre, client.prenom, client.nom));
}
} catch (Exception e) {
Console.WriteLine(e);
}
}
}
}
第 12 行中,使用了 C 语言代理的 [Client] 类,而我们刚才看到它实际上名为 [client]。 正是第 3 行的声明,使我们能够使用 [Client] 代替 [client]。这让我们能够遵守类名的编码规范。 同样在第12行,使用的是方法 [getAllClients],因为这是它在 C 代理中的名称。根据 C# 命名规范,该方法应命名为 [GetAllClients]。
运行前面的程序 [1] 会得到 [2] 中显示的结果。
5.2. 首个 ASP.NET 客户端 2008
现在,我们将编写第一个 ASP.NET / C# 客户端,用于显示客户列表。
![]() |
在此架构中,有两台Web服务器:
- 一个运行远程 Web 服务的服务器
- 运行远程 Web 服务客户端的 Web 服务器
我们将使用 Visual Web Express 2008 SP1 版本创建 ASP.NET 客户端 Web 项目。下文将介绍若未安装 Visual Web Express 2008 SP1 版本时,如何创建相同项目。
![]() |
创建一个名为 web [1, 2, 3] 的应用程序。所创建的项目可在 [7] 中查看。
![]() |
- 在 [5] 中,右键单击项目名称,即可添加 Web 服务引用。
- 在 [6] 中,指定 Web 服务的 WSDL 文件的 URI(参见第 4.10.2 节)。
- 在 [7] 中,要求向导发现该 URI 所暴露的 Web 服务
![]() |
- 在 [8] 中,显示已找到的 Web 服务;在 [9] 中,显示该服务暴露的方法。
- 在 [10] 中,指定应生成代理 C 类所在的命名空间
- 在 [11] 中,显示生成的 Web 服务引用
双击引用 [Ws.Rdvmedecins] [12],将显示为 C 代理生成的类和接口:
![]() |
- 在 [1] 中,双击打开的对象浏览器。
- 在 [2] 中,选择命名空间 [ListeDesClients1.Ws.RdvMedecins],该命名空间即生成的 C 代理的命名空间。 第一个项 [ListeDesClients1] 是所创建的应用程序 ASP.NET 的默认命名空间(我们将其命名为 ListeDesClients1)。 第二个术语 [Ws.Rdvmedecins] 是我们在向导中为 C 代理指定的命名空间。最终,C 代理的对象属于命名空间 [ListeDesClients1.Ws.RdvMedecins]。
- 在 [3] 中,生成的 C 代理对象
![]() |
- 在 [4] 中,[WsDaoJpaService] 是本地实现远程 Web 服务方法的类。
- 在 [5] 中,包含类 [WsDaoJpaService] 的方法。其中包含远程 Web 服务的方法,例如 getAllClients 对应 [6]。
让我们来查看生成的实体代码:
![]() |
在上述的 [1] 中,我们请求查看 [client] 类的代码:
public partial class client : personne {
}
...
public partial class personne {
...
public long id {
...
}
在上文中,我们仅保留了研究所需的代码。
- 第1行:类[client]继承自类[personne],这与Web服务中的情况一致。
- 第 5 行:类 [personne]
- 第 7 行:类 [personne] 的一个公共属性
此处的代码与第 5.1 节中已注释的 C# 客户端代码类似。
- 生成的 C 语言代理的命名空间是其创建向导中定义的,并以 Web 项目本身的命名空间为前缀:ListeDesClients1.Ws.RdvMedecins
- 本地实现远程 Web 服务方法的代理类名为 WsDaoJpaService。
- 类名和属性名均以小写字母开头
我们可以编写一个名为 [Default.aspx] 的页面来显示客户列表。该页面如下所示:
![]() |
编号 | 类型 | 名称 | 角色 |
MultiView | 视图 | 视图容器 | |
视图 | VueClients | 包含客户列表的视图 | |
重复器 | RepeaterClients | 以项目符号列表的形式显示客户列表 | |
View | VueErreurs | 显示可能出现的错误的视图 | |
标签 | LabelErreur | 错误文本 |
此页面的呈现代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ListeDesClients1._Default" %>
<%@ Import Namespace="ListeDesClients1.Ws.RdvMedecins" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Liste des clients</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:MultiView ID="Vues" runat="server">
<asp:View ID="VueClients" runat="server">
Liste des clients :<br />
<br />
<ul>
<asp:Repeater ID="RepeaterClients" runat="server">
<ItemTemplate>
<li>
<%#(Container.DataItem 作为客户端).姓%>,
<%#(Container.DataItem 作为客户端).名%>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</asp:View>
<asp:View ID="VuesErreurs" runat="server">
L'erreur suivante s'est produite :<br />
<br />
<asp:Label ID="LabelErreur" runat="server"></asp:Label></asp:View>
</asp:MultiView><br />
</div>
</form>
</body>
</html>
请注意,第 3 行需要导入 Web 服务 C 代理的命名空间 [ListeDesClients1.Ws.RdvMedecins],以便能够访问第 20 和 21 行中的类 [client]。
与展示页面 [Default.aspx] 关联的控制代码 [Default.aspx.cs] 如下:
using System;
using ListeDesClients1.Ws.RdvMedecins;
namespace ListeDesClients1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
// 远程层 [dao] 的本地代理实例
WsDaoJpaService dao = new WsDaoJpaService();
// 客户端视图
Vues.ActiveViewIndex = 0;
// 客户端视图初始化
RepeaterClients.DataSource = dao.getAllClients();
RepeaterClients.DataBind();
}
catch (Exception ex)
{
// 错误视图
Vues.ActiveViewIndex = 1;
//错误视图初始化
LabelErreur.Text = ex.ToString();
}
}
}
}
- 第 8 行:在页面初始加载时执行方法 Page_Load。每次客户端请求该页面时都会进行此加载。
- 第 13 行:实例化本地代理 C。该代理 C 实现了远程 Web 服务的接口。应用程序将与该代理 C 进行交互。
- 第 15 行:若在实例化本地代理 C 时未发生异常,则应显示名为“VueClients”的视图,即 c.a.d。 即页面“视图”中的 MultiView 视图中的第 0 号视图。
- 第 17 行:répéteur 的数据源是代理 C 的 getAllClients 方法提供的客户列表。
- 第 23 行:如果在实例化本地代理 C 时发生异常,则应显示名为“VueErreurs”的视图,c.a.d。 页面中 MultiView “视图”下的第 1 个视图。
- 第25行:异常显示在label“LabelErreur”中。
运行 Web 项目后,结果如下:
![]() |
5.3. 第二个 ASP.NET 客户端(2008 版)
现在,我们编写第二个 ASP.NET / C# 客户端,这次使用的是 SP1 版本之前的 Visual Web Developer Express 2008 版本。
![]() |
创建客户端 Web 项目 .NET:
![]() |
创建一个名为 web [1, 2] 的网站,该网站名为 [ListeDesClients] [3]。
![]() |
- 在 [4] 中,将 Web 项目
- 在 [5] 中,通过右键单击项目名称,像之前那样添加一个服务引用。
- 在 [6] 中,项目在添加了远程 Web 服务引用后
与之前研究的Web项目SP1不同,无法通过对象浏览器访问Web服务客户端的对象。
需知:
- 生成的 C 代理的命名空间是其创建向导中定义的:Ws.RdvMedecins
- 本地实现远程 Web 服务方法的代理类名为 WsDaoJpaClient。
- 类名和属性名均以小写字母开头
我们可以编写一个名为 [Default.aspx] 的页面来显示客户列表。该页面如下所示:
![]() |
编号 | 类型 | 名称 | 角色 |
MultiView | 视图 | 视图容器 | |
视图 | VueClients | 包含客户列表的视图 | |
重复器 | RepeaterClients | 以项目符号列表的形式显示客户列表 | |
View | VueErreurs | 显示可能出现的错误的视图 | |
标签 | LabelErreur | 错误文本 |
此页面的呈现代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Import Namespace="Ws.RdvMedecins" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Liste des clients</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:MultiView ID="Vues" runat="server">
<asp:View ID="VueClients" runat="server">
Liste des clients :<br />
<br />
<ul>
<asp:Repeater ID="RepeaterClients" runat="server">
<ItemTemplate>
<li>
<%#(Container.DataItem 作为客户端).姓%>, <%#(Container.DataItem 作为客户端).名%>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</asp:View>
<asp:View ID="VuesErreurs" runat="server">
L'erreur suivante s'est produite :<br />
<br />
<asp:Label ID="LabelErreur" runat="server"></asp:Label></asp:View>
</asp:MultiView><br />
</div>
</form>
</body>
</html>
请注意,第 2 行必须导入 Web 服务 C 代理的命名空间 [Ws.RdvMedecins],以便访问第 19 行中的类 [client]。
与展示页面 [Default.aspx] 关联的控制代码 [Default.aspx.cs] 如下:
using System;
using Ws.RdvMedecins;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
// 远程层 [dao] 的本地代理实例
WsDaoJpaClient dao = new WsDaoJpaClient();
// 客户端视图
Vues.ActiveViewIndex = 0;
// 客户端视图初始化
RepeaterClients.DataSource = dao.getAllClients();
RepeaterClients.DataBind();
}
catch (Exception ex)
{
// 错误视图
Vues.ActiveViewIndex = 1;
//错误视图初始化
LabelErreur.Text = ex.ToString();
}
}
}
该代码与上一版本的代码类似。运行该Web项目后,结果如下:




















