开发者社区> 技术小甜> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

当ASP.NET撞上JSF之构建应用程序的异同

简介:
+关注继续查看
理想情况下,ASP.NET和JSF web页面应该包含很少的代码而且只是包含必要的HTML和标签来生成页面的组件,一个页面的事件逻辑驻留于代码文件中。在ASP.NET中,每个web 页面与一个相应的子类化页面ASP.NET类的.NET类文件相关联。有时,这些文件被引用为"code-behind"文件。在JSF中,每个web页 面都有一个相关联的支持JavaBean类。ASP.NET的code-behind文件和JSF支持bean都包含页面属性(例如标签和输入域)。 JSF bean是用Java编写的,而ASP.NET code-behind文件可以使用任何.NET语言(例如VB.NET或C#)编写。ASP.NET code-behind类负责处理相关联的页面事件。这个处理一个组件事件的Java类不必是页面的支持JavaBean。过一会我们再讨论它。值得注意 的是,在ASP.NET中分离的code-behind文件可能是不必要的-有可能在页面本身的代码中实现事件处理。然而,一般来说,这被认为是一种不好 的编码实践,因为这样以来将会导致混淆HTML和代码问题。

  下面是我们的示例ASP.NET和JSF应用程序的两幅快照。由于两种组件的内在特性以及我也没有对之应用匹配的视觉式样,所以它们看起来略微有些不同。在两个页面中,显示一个会议房间表格,还有进一步了解相应房间的View按钮和预订该房间的Reserve按钮。

按此在新窗口浏览图片
ASP.NET程序快照
按此在新窗口浏览图片
JSF程序快照
  上面这些组件都是通过拖动添加的,然后通过修改一个属性面板定制它们的外观和行为。当然,我还可以通过编辑它们在HTML源码中的标签来定制这些组件。在此不赘述。下面,我们重点分析一下在这些web页面背后的代码文件,从而进一步分析事件代码。

我认为,以表格形式显示数据是不错的开始,因为这种情况在应用程序是常见的。为此,ASP.NET和JSF也都没有忽略这种实现,两类被显示的组件都提 供了内置功能来实现诸如排序和分页显示等效果。在ASP.NET 2.0之前,ASP.NET就已经提供了许多数据显示组件,其中DataGrid组件是使用最广泛的。另外,ASP.NET 2.0发行中引入了一个新的GridView组件。在本例中,我使用了这种组件,因为它添加了一些新的有用的特性。ASP.NET组件利用ADO.NET 技术,这也是整个.NET框架的数据存取技术-ADO.NET提供了一种健壮的对象模型来操作各种类型的数据源。例如,Dataset对象允许你以一种断 开的方式来使用数据。这意味着,为了使用数据,你的应用程序并不需要连续地连接到数据库上。一个Dataset还允许你隐蔽在它的接口后面的数据库细节, 从而使你以对应用程序的其它部分极小的影响来切换数据库。我在本例中所使用的JSF组件是一个与Java Studio Creator一同发行的表格组件。它使用一个DataProvider对象-它允许你利用JDBC Rowset技术。JDBC Rowset还能使你在断开的情况下以一种易于使用的方式使用数据库。
  每个这些启动页面都各自包含一个单一的标签组件实现页面头部。在一个页面的事件处理器中可以存取和修改该页面组件。通过在可视化编辑器中简单地 双击该组件,你可以把大多数的事件挂接到一个组件上。而且,这将会把你导向代码文件中,在此你可以添加代码。如我们前面已经注意到的,与web页面相关联 的ASP.NET页面类正是你的事件代码将驻留的地方。在JSF中,并不象这样简单。JSF事件遵循Observer设计模式。需要被通知某些事件的对象 都要把它们自己注册为该事件相应的听者(listener)。在JSF中共有两种类型的事件:Value Changed事件和Action事件。典型地,Value Changed事件发生在例如列表框选择这样的行为中,而Action事件将产生例如按钮点击这样的用户行为。任何Java类都能够响应于一个web表单 的事件。然而,JSF页面的支持bean是实现事件方法的很方便的位置,例如Sun Java Studio Creator就假定你把相应的实现放置于此。

当启动一个ASP.NET应用程序时,位于一个文件web.config中的配置信息 被分析和应用。每个ASP.NET应用程序都有一个web.config。我通过把连接串存储到Mysql数据库中来利用这个文件。web.config 经常用来存储数据库连接串以达到在代码外保持这个连接。下面展示了web.config文件的一部分代码片断:

<connectionStrings>
<add name="MyConnectionString"
connectionString="Driver={MySQL ODBC 3.51 Driver};server=localhost;database=test;uid=testuser;pwd=testpassword"
providerName="System.Data.Odbc"/>
</connectionStrings>

   JSF应用程序依赖于典型的基于Servlet的Java应用程序架构。一个'WEB-INF'文件夹下带有一些子文件夹和一个包含应用程序设置(很类 于ASP.NET的web.config)信息的文件web.xml。注意,这里的Mysql连接串并不保存在这个JSF应用程序的web.xml文件 中。而是,Studio Creator自动地把该连接添加到服务器的配置文件中,而我们的应用程序通过JNDI(Java命名和目录接口)来存取它-这是一种搜索J2EE服务的 常用方式。每一个JSF应用程序的web.xml文件都指定一个FacesServlet类型的Java Servlet。这个FacesServlet负责配置应用程序的相应于它的JSF使用的设置。在一个JSF应用程序中,所有的请求都要"流经 "FacesServlet。这个控件Servlet控制基于组件事件结果的应用程序页面之间的流程。这被称作"Front Controller"设计模式。在ASP.NET中没有使用这种级别的间接方式,则是由页面本身控制页面流,称作"Page Controller"设计模式。通过参考存储在一个配置文件faces-config.xml中的页面到页面映射,这个FacesServlet知道如 何路由请求。这个配置文件也包含一些我们将要强调的JSF配置信息。

  另外,ASP.NET和JSF页面拥有非常相似的生命周期。在前 面,我们已经讨论了组件是如何基于用户行为生成事件的,而事件仅是这种生命周期的一部分。从一种高级视图角度来观察一个页面的生命周期,其大致流程为:用 户发出一个请求并初始化页面,然后,页面的整个组件树被读入并且组件的状态被恢复,根据用户行为处理事件并更新组件值,最后结果页面被生成到用户端。当 然,实际情形可能比这更为复杂些,而且还有一些重要阶段(例如数据校验)掺杂在这些步骤中。在JSF和ASP.NET之间的一个关键区别在于,组件如何被 生成到用户。ASP.NET组件在页面上生成自己;而在JSF中,组件能够自我生成,但是更为经常的是,它们把生成代理到特定的Renderer对象(可 用于一个RenderKit中)。针对每一种不同类型的描述媒体提供一种不同的RenderKit。每一个JSF实现都会提供一个缺省的HTML RenderKit。这意味着,同一个JSF组件可能被以不同形式生成到一种web浏览器或无线设备上-通过简单地加入一个不同的Render对象,这是 一种相当强的生成能力。

  一个很方便的添加代码而又不依赖于任何特定类型的用户请求的时机是当页面对象被初始化时。ASP.NET提供 了一个Page_Load事件-它当用户作任何类型的页面请求时被调用。在JSF页面中,你可以使用类构造器方法来实现同样的页面初始化逻辑。下面是两种 应用程序的相应于用户在数据显示组件上所做动作的事件处理代码。

//ConferenceRooms.Java事件代码:
public String btnViewReservations_action() {
//把选定行的相应的房间的id和name保存起来...
Object id = getValue("#{currentRow.value['conference_rooms.room_id']}");
Object name = getValue("#{currentRow.value['conference_rooms.room_name']}");
ReservationsSessionBean resBean =(ReservationsSessionBean)this.getBean("ReservationsSessionBean");
resBean.setRoomId(id.toString());
resBean.setRoomName(name.toString());
return "view";
}
public String btnMakeReservation_action() {
Object id = getValue("#{currentRow.value['conference_rooms.room_id']}");
ReservationsSessionBean resBean = (ReservationsSessionBean)this.getBean("ReservationsSessionBean");
resBean.setRoomId(id.toString());
return "reserve";
}
//ConferenceRooms.cs事件代码
protected void GrdVwRooms_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Sort")) {
SortDirection sd;
if (((SortDirection)Session["sortRooms"]).Equals(SortDirection.Ascending)) {
sd = SortDirection.Descending;
}
else {
sd = SortDirection.Ascending;
}
Session.Add("sortRooms", sd);
this.GrdVwRooms.Sort(e.CommandArgument.ToString(), sd);
}
else
{
DataKey data = GrdVwRooms.DataKeys[Convert.ToInt32(e.CommandArgument)];
Session.Add("roomId", data.Values["room_id"].ToString());
Session.Add("roomName", data.Values["room_name"].ToString());
if (e.CommandName.Equals("Reserve")) {
Server.Transfer("Reserve.aspx");
}
else
{
if (e.CommandName.Equals("View")) {
Server.Transfer("RoomReservations.aspx");
}
}
}
}

   这里的代码有一点不同,Java类被分成了两个方法。这两个Java事件都是Action事件。我把这个ASP.NET应用程序中的所有的事件逻辑都纳 入到一个单一的RowCommand事件中并且查问该事件的参数来决定哪一个用户事件发生。在这个特殊的事件处理器中,我实现了view和reserve 按钮点击相应事件,还有针对于ASP.NET组件情况的排序请求。两种应用程序都保存roomId和roomName属性以便于应用程序的后面使用。具体 请参考本文相应源码中的ConferenceRooms.java和ConferenceRooms.cs文件。记住,这些类文件中的大多数代码都是工具 生成的,你可以使用编辑器提供的代码重叠功能来使代码更具可读性。在这些事件方法中,你可以立即存取这个页面组件的值以实现读取和修改。ASP.NET和 JSF保存视图状态-通过把它写到隐藏的HTML域中并把它从一个请求传递到另一个请求。当然,使用相同的方法来存储状态的传统型ASP和JSP应用程序 仍然是可用的。例如,在ASP.NET和JSF页面中,房间id和name都被放置到用户的Session中,这样它就可以在后面被检索。
  注意,在上面的事件代码中,ASP.NET文件调用一个方法"Server.Transfer"实现把控制传递给另一个页面。然而,在JSF事 件代码中,你不会找到这样的到另一个页面的直接的参考,而仅有返回串"view"和"reserve"。这是因为,JSF中经由我们更早讨论的faces -config配置文件处理页面流问题,任何使用过开源框架Struts的Java开发者应该对此很熟悉。在ConferenceRooms.jsp文件 的faces-config.xml文件中共有两个入口-字符串"view"和"reserve"。在运行时刻,应用程序使用这些字符串查询页面地址。下 面是在ConferenceRooms.jsp页面的faces-config文件中发现的XML形式的导航规则。我是使用Java Studio Creator中的一个可视化设计器创建的这些映射。

<navigation-rule>
<from-view-id>/ConferenceRooms.jsp</from-view-id>
<navigation-case>
<from-outcome>view</from-outcome>
<to-view-id>/RoomReservations.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>reserve</from-outcome>
<to-view-id>/ReserveRoom.jsp</to-view-id>
</navigation-case>
</navigation-rule>

  按此在新窗口浏览图片
  可视化设计器展示了在Java Studio Creator中的导航规则

   这个faces-config文件也是你列举与你的JSP页面文件相关联的所有Java Bean的地方。事实上,你可以通过这个文件配置任何你的应用程序需要参考的Java对象-这些Java对象被参考为'managed beans'。所有的JSF支持bean都将在这个配置文件中被列举为托管bean,但是任何你需要的其它对象也都可以在这里找到。一个托管bean包含 完全限定的类名、该bean(是把它存储在应用程序的Request,Session还是应用程序级)的使用范围以及当参考这个bean时要使用的名字。 在下面的XML中,列举出了初启web页面的支持bean,还有一个名为ReservationsSessionBean(我们使用它来共享应用程序中的 数据)的EJB的入口:

<managed-bean>
<managed-bean-name>ReservationsSessionBean</managed-bean-name>
<managed-bean-class>webreservations.ReservationsSessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>ConferenceRooms</managed-bean-name>
<managed-bean-class>webreservations.ConferenceRooms</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

   让我们再回到前面的应用程序中来,我们的查看预订信息的请求把我们引向ASP.NET版本的RoomReservations.cs.aspx(相应于 JSF版本的RoomReservations.jsp)。在相关的代码文件(RoomReservations.cs和 RoomReservations.java)中,该事件代码检索存储于前一个页面中的房间id并且使用它来过滤第二个表格(它列举有关该房间的预订情 况)。在数据表格上面的标签被修改以引用相应房间的名字。

按此在新窗口浏览图片
ASP.NET

按此在新窗口浏览图片>
JSF


   一个delete按钮相应于删除每一行数据,这两个组件都允许你轻松地修改表中的数据。最后,每一个表单都包含一个按钮-它把你导向另一个表单以添加对 该房间的新的预订。这些表单显示于下面图中。注意,在图中由Java Studio Creator和Visual Studio实现的日历组件在显示上有所不同,但是实现相同的目的。
按此在新窗口浏览图片
ASP.NET

按此在新窗口浏览图片
JSF















本文转自朱先忠老师51CTO博客,原文链接:http://blog.51cto.com/zhuxianzhong/59805 ,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
4.5管道实现机制和模拟构建管道「深入浅出ASP.NET Core系列」
原文:4.5管道实现机制和模拟构建管道「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁、等公交,积少成多,水滴石穿,谢谢关注。 管道实现机制 要了解管道的实现机制,我们必须要深入框架的源码,幸亏微软开源了,我们可以访问GitHub的地址来下载源码。
720 0
4.5管道实现机制和模拟构建管道「深入浅出ASP.NET Core系列」
要了解管道的实现机制,我们必须要深入框架的源码,幸亏微软开源了,我们可以访问GitHub的地址来下载源码。
1385 0
如何构建ASP.NET MVC4&JQuery&AJax&JSon示例
背景:   博客中将构建一个小示例,用于演示在ASP.NET MVC4项目中,如何使用JQuery Ajax。 步骤: 1,添加控制器(HomeController)和动作方法(Index),并为Index动作方法添加视图(Index.cshtml),视图中HTML如下: 输入你的姓名: 输入你的年龄: 提交 清空   视图中包含两个文本框,分别用来输入名字和年龄,包含连个按钮,分别用来提交信息和清空文本框的内容,同时包含一个段落,用来显示Ajax返回的数据信息。
681 0
菜鸟入门【ASP.NET Core】8:Middleware管道介绍、自己动手构建RequestDelegate管道
中间件:是汇集到以处理请求和响应的一个应用程序管道的软件。 每个组件: 可以选择是否要将请求传递到管道中的下一个组件。 之前和之后调用管道中的下一个组件,可以执行工作。 使用请求委托来生成请求管道。
1041 0
【推荐】【给中高级开发者】构建高性能ASP.NET应用的几点建议
本篇目录 早期阶段就要对应用进行负载测试 使用高性能类库 你的应用是CPU密集还是IO密集的 使用基于Task的异步模型,但要慎重 分发缓存和会话(session)状态 创建Web Gardens 巧妙地使用缓存和懒加载 不要在MVC视图中放C#代码 适当时使用Fire & Forget 为x64 CPU创建 使用服务器上的监视和诊断工具 分析运行中的应用 如果你在构建一个面向公众的web站点,那么在项目结尾时你想要实现的就是web负载性能良好。
1126 0
ASP.NET Core MVC中构建Web API
在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能。 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文件夹,填加后,选中API文件夹, 选择新建项,选择填加Web API控制器,要注意控制器在命名时,是以Controller结尾的,这个不能改,前面的随意,比如,此处以NoteController.cs为例 填加后,打开NoteController.cs,系统已经帮我们构建好了一些基础的功能,我们需要在其基础上进行一些个性化修改使其成为我们自己的代码。
719 0
Asp.net 构建可扩展的的Comet Web 应用(二)
说明 如果你已经阅读了我之前的一篇文章《Asp.net构建可扩展的的Comet Web 应用》。你应该能够理解我将要写的内容。我解释了Comet技术并且解释了怎样用asp.net构建具有可扩展性的应用。
991 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载