`
CL315917525
  • 浏览: 233060 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

深入理解JSF原理与执行过程

 
阅读更多

转载于http://www.ibm.com/developerworks/cn/java/j-jsf2/
JSF 生命周期:概述
JSF 程序生命周期的 5 个阶段如下(注意每个阶段的事件处理):
恢复视图
应用请求的值;处理验证
更新模型值;处理事件
调用程序;处理事件
进行响应;处理事件
这 5 个阶段显示了 JSF 通常处理 GUI 的顺序。虽然这个清单列出了每个阶段中事件处理的可能执行顺序,但是 JSF 的生命周期很难是固定一成不变的。您可以通过忽略某个阶段或合并整个生命周期从而对执行顺序进行修改。例如,如果一个无效的请求值被拷贝到一个组件中,那么当前的视图就会重新显示,而有些阶段就可能不会执行。在这种情况中,您可以执行一个 FacesContext.responseComplete方法调用,将用户重定向到一个不同的页面上,然后使用请求分发器(从 FacesContext中的请求对象中获得)将其转发到一个适当的 Web 资源上。另外,您可以调用 FacesContext.renderResponse重新显示原来的视图。(详细信息请参看下面的示例程序。)
关于本系列文章
这个 4 部分的系列文章专门用来消除那些怀疑论者对 JavaServer Faces(JSF)技术的恐惧、怀疑或疑虑(FUD),方法是给您一个机会自己通过一个一步步的、容易学习的格式来了解这种技术。通过这 4 篇文章的教程介绍,我们将提供一系列的例子简要介绍 JSF 的基本架构、特性和功能。一旦熟悉 JSF 处理事情的方法之后,我想您将发现很难再返回 Struts Model 2 风格的开发了。毕竟,在体验过 JSF 的事件驱动的 GUI 组件模型之后,谁还会希望重新经历 XML 配置的恶梦呢?
要掌握本系列教程的内容,您应该熟悉 Java 编程、JavaBeans(即事件模型和属性)、JavaServer Pages(JSP)、JSP Standard Tag Library Expression Language 以及 Web 开发的所有基本概念。
关键是让生命周期构成您的开发项目,而不完全依赖于生命周期。在需要时,您可以修改生命周期,而不用担心破坏您的程序。在大部分情况中,您会发现 JSF 的生命周期是值得遵守的,因为它的逻辑非常好。表单必须在任何应用程序逻辑执行之前进行验证,并且在进行验证之前,必须对域中的数据进行转换。遵守生命周期的规定,可以让您更自由地考虑有关验证和转换的问题,而不是请求处理本身的阶段。有一点非常重要:其他 Web 框架也都具有类似的生命周期;它们只不过是没有很好地进行宣传。
专注
有些使用 JSF 的开发者可能从来都不会编写一个组件,也不会对框架进行任何扩展;而另外一些人则专注于这种任务的开发。尽管 JSF 的生命周期与大部分那其他项目都是相同的,但是根据在项目中的角色您可以采用不同的阶段。如果您更专注于通用的应用程序开发,就可能会关注请求处理生命周期的中间阶段:
应用请求值
更新模型值
调用程序
如果您专注于 JSF 组件的开发,就可能会关注于整个生命周期中的第一个阶段和最后一个阶段:
恢复视图
进行响应
在接下来的几节中,我们将遍历 JSF 请求处理生命周期的每个步骤,包括事件处理和验证。了解了每个步骤的基本知识之后,我们将简要介绍一个示例程序,它可以展示这些步骤如何一起使用。在开始之前,首先来看一下图 1,这是一个有关 JSF 生命周期的图。

图 1. JSF 生命周期
 
回页首
阶段 1:恢复视图
在 JSF 生命周期的第一个阶段 —— 恢复视图—— 中,会有一个来自 FacesServlet控制器的请求。控制器会对请求进行考查,并提取出视图的 ID,这是由 JSP 页面的名字来确定的。
JSF 框架控制器使用这个视图 ID 来为当前的视图查找组件。如果这个视图尚未存在,那么 JSF 控制器就会创建它。如果这个视图早已存在,那么 JSF 控制器就会使用它。这个视图包含了所有的 GUI 组件。
生命周期的这个阶段表示为三个视图实例:新视图、原始视图和后视图,每个视图的处理方式都不相同。在 新视图的情况中,JSF 会构建 Faces页面的视图,并将事件处理程序和验证程序绑定到组件上。这个视图被保存在一个 FacesContext对象中。
FacesContext对象包含了 JSF 用来管理当前会话中当前请求的 GUI 组件状态所需要的所有状态信息。FacesContext将视图保存在自己的 viewRoot属性中;viewRoot包含了当前视图 ID 的所有 JSF 组件。
在 原始视图的情况中(第一次加载的是一个页面),JSF 会创建一个空视图。这个空视图会在用户事件产生时进行填充。JSF 可以直接从原始视图过渡到进行响应的阶段。
在 后视图(postback)的情况中(用户返回之前访问过的页面),包含页面的视图早已经存在了,因此只需要进行恢复就可以了。在这种情况中,JSF 就使用现有视图的状态信息来重构状态。后视图的下一个阶段是应用请求值。
回页首
阶段 2:应用请求值
应用请求值阶段的目的是让每个组件检索自己当前的状态信息。这些组件必须首先通过 FacesContext对象进行检索或创建(使用其值)。虽然组件值也可以从 cookie 或头文件中进行检索,但是它们通常是通过请求参数进行检索的。
如果一个组件的即时事件处理属性 没有设置为 true,那么就会对这些值进行转换。因此,如果 域被绑定到一个 Integer属性上,那么该值就会被转换为一个 Integer类型。如果值的转换失败了,那么就会生成一个错误消息,并在 FacesContext中进行排队,在产生响应的阶段会显示其中的消息,同时还会显示所有的验证错误。
如果一个组件的即时事件处理属性 的确被设置为 true,那么这些值就会被转换为适当的类型,并进行有效性验证。然后转换后的值会被保存到组件中。如果值转换或值的有效性验证失败了,就会生成一个错误消息,并在 FacesContext中进行排队,在产生响应的阶段会显示其中的消息,同时还会显示所有的验证错误。
即时事件处理
JSF 的即时事件处理属性用来处理那些通常不必要对整个表单进行有效性验证的事件。例如,假设一个雇员表单中有一个单选按钮来说明他是否是经理。当他选中 Manager 选项时,应用程序就会为经理生成一些内容。由于单选按钮只用来生成一个列表,而不需要用户填写整个表单,因此不需要对整个表单进行有效性验证。在这种情况中,您就可以使用即时事件处理。有关这个主题的更详细内容,请参阅 即时事件处理。
处理验证
生命周期中的第一个事件处理发生在应用请求值阶段之后。在这个阶段中,每个组件都有一些值需要根据应用程序的验证规则进行有效性验证。这些验证规则可以是预先进行定义的(JSF 中提供的),也可以由开发者进行定义。用户所输入的值会与这些验证规则进行比较。如果说输入的值无效,就会向 FacesContext中添加一个错误消息,并且该组件会被表示为无效的。如果一个组件被表示为无效的,那么 JSF 就会转到产生响应的阶段,在这个阶段中会显示当前的视图,以及验证错误消息。如果没有有效性验证错误,那么 JSF 就会转到更新模型值的阶段。
回页首
阶段 3:更新模型值
JSF 应用程序生命周期中的第三个阶段 —— 更新模型值—— 负责更新服务器端模型的实际值,通常来讲,这都是通过更新后台 bean(称为管理 bean)的属性实现的。只有那些与组件值绑定在一起的 bean 属性才会被更新。注意这个阶段发生在有效性验证之后,因此可以确保拷贝到 bean 属性的值都是有效的(至少在表单域一级都是有效的;在业务规则一级仍可能无效)。
回页首
阶段 4:调用程序
在生命周期的第四个阶段 —— 调用程序—— 中,JSF 控制程序会调用程序来处理 表单的提交操作。组件值已经经过了类型转换和有效性验证,并被应用到模型对象中了,因此您现在可以使用它们来执行应用程序的业务逻辑了。
在这个阶段,您还可以为一个给定的序列或很多可能的序列指定后面的逻辑视图,这可以通过为一次成功的表单提交定义一个特定的结果并返回这个结果来实现。例如:在成功输出时,将用户重定向到下一页中。要让这种导航工作能够起作用,您需要在 faces-config.xml 文件中创建一个到 成功输出的映射作为一条导航规则。一旦导航发生之后,您就转换到生命周期的最后一个阶段了。
回页首
阶段 5:进行响应
在生命周期的第五个阶段 —— 进行响应—— 中,您可以在视图中显示当前状态中的所有组件。
图 2 是 JSF 生命周期的第五个阶段的一个对象状态图,包括时间有效性验证和处理。

图 2. JSF 生命周期的五阶段
 
回页首
范例
现在您已经对 JSF 生命周期的阶段有了基本的了解,下面我们将向您介绍在一个范例 Web 应用程序中,这些阶段是如何协同工作的。除了展示 JSF 生命周期的基本功能之外,这个应用程序还会利用一些通用的 JSF GUI 组件,例如 Radio List, List, Text Field, Label, Panel 等等,这样您就可以亲自体验一下在 第 1 部分中曾经简要讨论过的这些组件。
这个示例程序还会展示在 JSF 中使用其他 Java 技术的两种方法。它将组合使用 JSF 和 JavaScript 来启用即时事件处理(在那些对整个表单进行验证是多余的情况中),其布局是由 Struts Tiles 进行管理的。 虽然 Struts Tiles 并不是 JSF 的一个必要部分,但是 tiles 通常用来为一个程序中的所有 JSF 页面提供一致的外观。要学习更多有关 Struts Tiles 的内容,请参阅 参考资料。
程序设置
这个示例 Web 程序实际上是一个非常简单的创建、阅读、更新并删除(CRUD)一个在线 CD 仓库中库存的程序。它包括一个表单,让用户可以向系统中输入新 CD;有一些单选按钮,让用户选择音乐的分类。当用户选择一个分类时,就启动一些 JavaScript 脚本将这个表单立即发回服务器。程序组合采用 JSF 和 JavaScript 技术来处理一个组件,而不是整个页面,这种技术称为 即时事件处理。在这种情况中,您可以填充一个子类清单,而不用验证表单的其他内容。
这个示例程序还包括一个 CD 清单,它将展示如何使用 JSF 的 dataTable。从这个页面中,最终用户可以根据标题或者艺术家对 CD 清单进行排序。
类和方法
图 3 列出了这个示例程序的类。图中列出了 4 个类,我们只关注其中的 3 个:StoreManagerDelegate、CD和 StoreController。

图 3. 示例程序类
 
StoreManagerDelegate类是这个程序的业务代表。它为整个模型呈现了主界面。CD类是一个数据转换对象(DTO)。如果这是一个真实的程序,那么 StoreManagerDelegate类就会为添加、删除和编辑 CD 实现所有的业务规则,还会负责使用一个数据访问对象(DAO)将 CD存储到一个永久的存储介质中。StoreManagerDelegate和 CD 包含了一些用于这个 MVC 程序的 模型。
StoreController类是本例中的主要后台 bean。StoreController类是 GUI 世界和模型世界之间的黏合剂。它将自己的很多行为都委托给 StoreManagerDelegate进行处理。StoreController是这个 MVC 程序的 控制程序。
StoreController类展示了如何构建一个可排序的 CRUD 清单。它具有以下与 CRUD 相关的方法:editCD、addNew、addCD以及 updateCD。StoreController还负责将模型对象呈现给表单。在这种情况中,它使用 cd属性将当前的 CD对象呈现给 CD 表单,该属性的类型就是 CD。
回页首
开始编码
开始编写这个示例程序的最好方法是遍历它的使用案例:
新增 CD
编辑现有的 CD
根据标题对 CD 进行排序
根据艺术家对 CD 进行排序
第三个使用案例和第四个使用案例的代码基本上是相同的,因此我将向您展示如何根据标题进行排序,并将第四个使用案例留作练习,请您自行完成。我们很快就会对使用案例进行编码,但是首先让我们来了解一下完成后的应用程序的页面将是什么样子。
并非真正的 CRUD
注意这个程序并不是一个真正的 CRUD 清单程序。它实际上只是一个 CRU清单,因为我将 D留给您自己实现了。但是无须担心,它非常简单。删除操作的步骤与编辑操作的步骤非常类似,后者在本文中已经实现了。您可以完成 CRUD 吗?
图 4 显示了具有可排序列的 CD 清单页面。

图 4. 具有可排序列的 CD 清单页面
 
图 5 显示了具有分类组件的 CD 表单页面。

图 5. 尚未选择分类的 CD 表单页面
 
图 6 显示了具有分类和子类组件的 CD 表单页面。

图 6. 已经选择了分类和子类组件的 CD 表单页面
 
回页首
使用案例 1:新增 CD
在该程序的第一个使用案例中,用户将添加一个新 CD:切换到 CD 清单页面上,点击 Add CD链接(这是在 listing.jsp 文件中定义的),如清单 1 所示。

清单 1. 在 listing.jsp 中定义的 Add CD 按钮
 <h:commandLink action="#{CDManagerBean.addNew}"> 
     <f:verbatim>Add CD</f:verbatim> 
 </h:commandLink> 

这个链接被绑定到 CDManagerBean的 addNew方法上。这个 addNew方法在 JSF 生命周期的调用程序阶段(最后一个阶段)被调用的。操作被使用 JSF 绑定表达式 #{CDManagerBean.addNew}绑定到这个方法上。CDManagerBean是这个程序的存储控制器的一个别名。CDManagerBean是这个控制器的逻辑名。控制器类是一个在 faces-config.xml 文件中定义的管理 bean,如清单 2 所示。

清单 2. 在 faces-config.xml 中定义的 StoreController 类
<managed-bean> 
  <description>
    The "backing file" bean that backs up the CD application
  </description> 
  <managed-bean-name>
    CDManagerBean
  </managed-bean-name> 
  <managed-bean-class>
    com.arcmind.jsfquickstart.controller.StoreController
  </managed-bean-class> 
  <managed-bean-scope>
    session
  </managed-bean-scope> 
</managed-bean>

准备表单
addNew()方法通过创建一个空 CD 来准备表单,如清单 3 所示。

清单 3. addNew()创建一个空 CD 表单
 [StoreController.java] 
 /** 
 * Prepare the cdForm to add a new CD. 
 * This gets executed before we prompt 
 * the user to add a new CD. 
 * 
 * @return success 
 */ 
 public String addNew() { 
    if (subCategoryList == null) { 
        subCategoryList = new HtmlSelectOneListbox(); 
    } 

    subCategoryList.setRendered(false); 
    this.cd = new CD(); 

    return "success"; 
 } 

addNew()方法通过创建一个新的 CD 来清空 CD 表单域。这个 CD 表单的域被绑定到 cd属性的属性中。这个方法还会将正在显示的子类清单置空。
返回成功结果
接下来,addNew()方法会被调用,控制权被重定向到成功映射页面,即 cdForm.jsp 文件。cdForm.jsp 文件是在 faces-config.xml 文件中定义的,如清单 4 所示。

清单 4. cdForm.jsp 是 addNew()的成功映射
 <navigation-rule> 
  <from-view-id>/listing.jsp</from-view-id> 
  ... 
  <navigation-case> 
    <from-action>#{CDManagerBean.addNew}</from-action> 
    <from-outcome>success</from-outcome> 
    <to-view-id>/cdForm.jsp</to-view-id> 
  </navigation-case> 
    
 </navigation-rule> 

清单 4 表明如果用户从清单切换到 addNew (#{CDManagerBean.addNew})操作,并且 addNew操作成功返回,那就会切换到 cdForm.jsp 页面。
设置 cdForm 和 panelGrid
cdForm.jsp是包含 CD 表单的表单。其中具有 ID、Title、Artist、Price、Category 和 Subcategory 的域。这些域被放到一个名为 panelGrid的容器中。JSF 组件,例如 AWT 组件,具有一些容器和组件。容器是一个包含其他组件的组件。这是一个 混合设计模式的例子。panelGrid有 3 列。每个域都各在一行中,还会有一个标签和消息用于显示该域的错误消息。cdForm和 panelGrid是在清单 5 中定义的。

清单 5. 定义 cdForm和 panelGrid 
<f:view> 
  <h2>CD Form</h2> 
 
  <h:form id="cdForm"> 
 
    <h:inputHidden id="cdid" value="#{CDManagerBean.cd.id}"/> 
 
    <h:panelGrid columns="3" rowClasses="row1, row2"> 
 
    <h:outputLabel for="title" styleClass="label"> 
      <h:outputText value="Title"/> 
    </h:outputLabel> 

    <h:inputText id="title" value="#{CDManagerBean.cd.title}" required="true"/>

    <h:message for="title" styleClass="errorText"/> 

    <h:outputLabel for="artist" styleClass="label"> 
      <h:outputText value="Artist"/> 
    </h:outputLabel> 

    <h:inputText id="artist" value="#{CDManagerBean.cd.artist}" required="true"/>

    <h:message  for="artist"  styleClass="errorText"/> 

    <h:outputLabel  for="price" styleClass="label"> 
      <h:outputText value="Price"/> 
    </h:outputLabel> 

    <h:inputText id="price" value="#{CDManagerBean.cd.price}" required="true"/>

    <h:message for="price" styleClass="errorText"/> 

    <h:outputLabel for="category" styleClass="label"> 
      <h:outputText value="Category"/> 
    </h:outputLabel> 

    <h:selectOneRadio id="category" value="#{CDManagerBean.cd.category}" 
      immediate="true" 
      onclick="submit()"
      valueChangeListener="#{CDManagerBean.categorySelected}"> 
      <f:selectItems value="#{CDManagerBean.categories}"/> 
    </h:selectOneRadio> 

    <h:message for="category" styleClass="errorText"/> 

    <h:outputLabel for="subcategory" styleClass="label"> 
      <h:outputText value="Subcategory"/> 
    </h:outputLabel> 
	
    <h:selectOneListbox id="subcategory" value="#{CDManagerBean.cd.subCategory}"
      binding="#{CDManagerBean.subCategoryList}"> 
      <f:selectItems value="#{CDManagerBean.subCategories}"/> 
    </h:selectOneListbox> 

    <h:message  for="subcategory"  styleClass="errorText"/> 

  </h:panelGrid> 

  <br /> 

  <h:commandButton id="submitAdd" action="#{CDManagerBean.addCD}" value="Add CD" 
    rendered="#{not CDManagerBean.editMode}"/> 

  <h:commandButton id="submitUpdate" action="#{CDManagerBean.updateCD}" 
    value="Update CD" rendered="#{CDManagerBean.editMode}"/> 

  </h:form> 
        
</f:view>  

关于代码的注释
每个输入域都将该域绑定到控制器的 cd属性的一个属性上。例如,标题的输入文本域被使用下面的 JSF 绑定表达式绑定到 cd属性上:value="#{CDManagerBean.cd.title}"。
您可能会注意到在清单 5 中几乎没有什么 HTML 语句。这是由于 panelGrid会生成大部分的 HMTL 语句。注意实际的外观是由与 panelGrid相关的样式表决定的。属性 rowClasses="row1, row2"会为正在修改的行设置 CSS 类。第一行是白色的,第二行是灰色的。您还可以为列或其他内容指定 CSS 类。JSF panelGrid组件可以方便地快速设置表单的布局。如果您希望实现 panelGrid没有提供的功能,就不能使用它:不过可以使用 HTML 自己设置组件的布局。然而,如果您发现自己在很多页面上都使用了定制的 HTML,那么就可能会考虑编写自己的定制组件。这种想法可以让您尽可能 DRY地重用 HTML 语句(DRY 是 don't repeat yourself的缩写,这个术语来自于 Dave Thomas 的 Pragmatic Programmer一书)。
关于清单 5 另外需要注意的是控制器有一个 editMode属性,由 cdForm.jsp 用于有选择地显示 submitAdd按钮或 submitUpdate按钮;submitAdd按钮是在表单不处于编辑模式时显示的。submitUpdate按钮是在表单处于编辑模式时显示的。这可以简化为编辑和添加模式使用相同的 JSP。(默认情况下,表单不处于编辑模式。)这种功能是由 cdForm.jsp 中的每个按钮上的呈现表达式实现的。例如,清单 6 列出了 submitAdd button rendered="#{not CDManagerBean.editMode}"上的呈现表达式。submitAdd按钮被使用表达式 (action="#{CDManagerBean.addCD}") 绑定到 addCD方法上。

清单 6. 使用 addCD()方法添加一个 CD
 [StoreController.java] 
 /** 
 * Add a cd to the store. 
 * 
 * @return outcome 
 */ 
 public String addCD() { 
    store.addCD(this.cd); 

    return "success"; 
 } 

对域进行有效性验证
在 addCD方法被调用之前,JSF 必须对 GUI 中的域进行有效性验证。这实际上非常简单,因为您还没有为域关联任何有效性验证条件。在应用请求值阶段,这些值被从请求参数拷贝到组件值中(这是由组件本身进行的)。现在,价格从一个字符串转换为一个浮点类型。如果用户为价格输入的是“abc”,那么转换为浮点类型的操作就会失败,控制权将被重新定向到 cdForm.jsp 页面上,供最终用户进行修正。与价格相关的 h:message将显示一个转换错误消息。如果所有的值都可以正常进行类型转换,并且现在都可以使用了(如果需要的话),那么您就可以进行有效性验证的处理了。由于这个示例程序并没有与组件关联任何有效性验证规则(在下一篇文章中我们将介绍这种特性),因此您可以继续进入更新模型值的阶段了。
在更新模型值的阶段中,会使用保存在 GUI 组件中的经过转换和有效性验证的值来调用 CD 的赋值方法。addCD()方法是在 调用程序阶段中被调用的。addCD()方法使用一个业务代理(store对象)来执行这个操作。addCD方法在系统中使用 store对象来存储 CD。由于 addCD方法会返回成功,因此接下来会显示这个清单,这是在 faces-config.xm 中定义的。在 faces-config.xml 中定义的导航规则如清单 7 所示。

清单 7. addCD成功输出的导航规则
 <navigation-rule> 
  <from-view-id>/cdForm.jsp</from-view-id> 
  <navigation-case> 
    <from-action>#{CDManagerBean.addCD}</from-action> 
    <from-outcome>success</from-outcome> 
    <to-view-id>/listing.jsp</to-view-id> 
  </navigation-case> 
  ... 
 </navigation-rule> 

回页首
使用案例 2:编辑 CD
这个示例程序的第二个使用案例也会在这个清单页面(listing.jsp)中启动。除了向您介绍如何编辑 JSF 页面中的数据之外,这个使用案例还将向您介绍 JSF dataTable组件。
这个清单页面使用一个 dataTable组件来显示 CD 的清单。dataTable的值被绑定到控制程序类 StoreController的 cds属性。cds属性的定义如清单 8 所示。

清单 8. 在 StoreController.java 中定义的 cds属性
 [StoreController.java] 
 /** List of cds for CD listing. */ 
 private DataModel cdModel = new ListDataModel(); 
 { 
    cdModel.setWrappedData(store.findTitleAsc()); 
 } 
 /** 
 * List of CDs in the system. 
 * 
 * @return Returns the cds. 
 */ 
 public DataModel getCds() { 
    return cdModel; 
 } 

cds属性是基于从存储对象 StoreManagerDelegate返回的 java.util.List的,这个对象是该程序的业务代理。cdModel对从 DataModel中的存储对象返回的清单进行了封装。DataModel是一个用于 dataTable的模型。
dataTable的定义如清单 9 所示。

清单 9. listing.jsp 中的 dataTable定义
 <f:view> 
    <h:form> 	
      <h:dataTable id="items" 
        value="#{CDManagerBean.cds}" 
        var="cd"
        rowClasses="oddRow, evenRow" 
        headerClass="tableHeader"> 

注意该值被绑定到控制程序的 cds属性上。rowClasses和 headerClass属性用来指定 CSS 类,后者用来定义 dataTable的外观。正如前面介绍的一样,JSF 严重依赖于 CSS 来定义 GUI 的外观。如果您并不了解 CSS(即您之前都是使用字体标签和 HTML 表来设置外观的),就可能会希望在灵活运行 JSF 之前首先来学习一下有关 CSS 的知识。
column 组件
Title、Artist和 Price域都是使用 column组件显示的,如清单 10 所示(此处只显示了 Title域)。

清单 10. 在 column 组件中添加域
 <h:column> 
    <f:facet name="header"> 
      ... 
        <h:outputText value="Title"/> 
    </f:facet> 
      <h:commandLink action="#{CDManagerBean.editCD}"> 
        <h:outputText value="#{cd.title}"/> 
      </h:commandLink> 
 </h:column> 

column组件是 dataTable的一个子组件。column组件使用一个子组件和一个 facet。facet是一个有名的子组件;它并不是一个子孙组件。column组件有一个名为 header的 facet,它定义了在 header 中显示的内容。对于本例来说,commandLink是 column组件的一个子孙组件。commandLink在一个链接中显示了 CD 的标题,该链接被绑定到操作 #{CDManagerBean.editCD}上。这个操作属性将 commandLink绑定到控制程序类的 editCD()方法上,如清单 11 所示。

清单 11. editCDcommandLink 的后台 bean 方法
 [StoreController.java] 
 /** 
 * Edit the CD. This get executed before the edit cdForm 
 * page gets loaded. 
 * 
 * @return outcome 
 */ 
 public String editCD() { 
    this.cd = (CD) cdModel.getRowData(); 
    this.cd = (CD) store.getCDById(cd.getId()); 

    if ((cd.getCategory() != null) || !"".equals(cd.getCategory())) { 
        this.subCategoryList.setRendered(true); 

        this.subCategories = getSubcategoriesList(cd.getCategory()); 
    } else { 
        this.subCategoryList.setRendered(false); 
    } 

    this.editMode = true; 

    return "success"; 
 } 

editCD()方法
editCD()方法是在 JSF 生命周期的调用程序阶段调用的。editCD()方法准备控制程序以使用编辑模式来显示 cdForm.jsp 页面。这是通过查看当前选定的 CD 来实现的,CD 是通过调用 cdModel.getRowData()方法来选择的。
注意 JSF DataModel允许您从比传统的 Web 应用程序更高的层次上使用数据。您并不需要对请求参数进行检查:只需要调用 cdModel.getRowData()方法向 DataModel(cdModel)查询已经选择了哪个 CD。这个更高级别的抽象对 Web 开发进行了相当程度的简化。
一旦取得当前选择的 CD 之后,就可以使用业务代理来加载该 CD 的最新拷贝了(store.getCDById())。在加载这个 CD 之后,store.getCDById()会激活 subCategory清单(假设这个 CD 已经关联了一个子目录),然后将 editMode属性设置为 true。回想一下,editMode属性是由 cdForm用来显示 Add 或 Update 按钮。最后,store.getCDById()方法返回 success。在清单 12 中重要的导航规则可以保证返回成功之后,切换到 cdForm.jsp 页面,如下所示。

清单 12. 一条重要的导航规则
 <navigation-rule> 
  <from-view-id>/listing.jsp</from-view-id> 
  <navigation-case> 
    <from-action>#{CDManagerBean.editCD}</from-action> 
    <from-outcome>success</from-outcome> 
    <to-view-id>/cdForm.jsp</to-view-id> 
  </navigation-case> 
  <navigation-case> 
    <from-action>#{CDManagerBean.addNew}</from-action> 
    <from-outcome>success</from-outcome> 
    <to-view-id>/cdForm.jsp</to-view-id> 
  </navigation-case> 
 </navigation-rule> 

updateCD()方法
CD 表单会加载并显示 CD 属性的属性设置。最终用户可以根据需要编辑所得到的表单,并在完成时点击 Update 按钮。Update 按钮是当用户处于 Edit 模式时所显示的惟一一个按钮,它只会在 editMode为 true时显示,如清单 13 所示。

清单 13. Update CD 按钮
 [cdForm.jsp] 

 <h:commandButton id="submitUpdate" 
  action="#{CDManagerBean.updateCD}" 
  value="Update CD" 
  endered="#{CDManagerBean.editMode}"/> 

Update 按钮被绑定到 updateCD()方法上。在调用 update 方法之前,JSF 必须对 GUI 中的域进行有效性验证。在应用请求值阶段,这些值被从请求参数中拷贝到组件值中(这是由组件本身完成的)。现在,价格被从一个字符串转换成了一个浮点类型。由于没有为组件关联任何有效性验证规则,因此如果所有请求的值都已经存在并经过转换了,就可以转换到生命周期的下一个步骤了。
更新模型值
在更新模型值阶段中,会使用保存在 GUI 组件中经过类型转换和有效性验证的值来调用 CD 的赋值函数。updateCD()方法是在调用程序阶段被调用的。updateCD()方法如清单 14 所示。

清单 14. updateCD()方法
 [StoreController.java] 

 /** 
 * Update the CD loaded on the form. 
 * 
 * @return success 
 */ 
 public String updateCD() { 
    store.updateCD(this.cd); 
    this.editMode = false; 

    return "success"; 
 } 

updateCD()方法可以代理业务代理的大部分职责。它将 editMode 设置为 false(这是默认值),并返回成功。成功输出将您重定向回清单页面中,在这个页面中您可以查看根据清单 15 中显示的导航规则新编辑的 CD。

清单 15. 成功的 UpdateCD 会将您带回 listing.jsp
 [faces-config.xml] 
 <navigation-rule> 
  <from-view-id>/cdForm.jsp</from-view-id> 
  ...    
  <navigation-case> 
    <from-action>#{CDManagerBean.updateCD}</from-action> 
    <from-outcome>success</from-outcome> 
    <to-view-id>/listing.jsp</to-view-id> 
  </navigation-case> 
 </navigation-rule> 

回页首
使用案例 3:对 CD 进行排序
我们要介绍的最后一个使用案例将向您展示如何对表进行排序。这个使用案例也是在 CD 清单页面上启动的。清单页允许根据标题和艺术家对 CD 按照升序或降序的顺序进行排列。在本例中,我将向您展示如何根据标题进行排序,并将根据艺术家进行排序留作练习。
标题头排序有一些到控制程序中排序方法的链接。清单 16 显示了在 listing.jsp 中是如何显示标题头的。

清单 16. 对 commandLinks 进行排序
[listing.jsp] 
<h:column> 
  <f:facet name="header"> 
    <h:panelGroup> 
      <h:outputText value="Title"/> 
      <f:verbatim>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[</f:verbatim> 
      <h:commandLink styleClass="smallLink" action="#{CDManagerBean.sortTitleAsc}">
        <h:outputText id="ascTitle" value="asc"/> 
      </h:commandLink> 
      <h:outputText value=","/> 
      <h:commandLink styleClass="smallLink" action="#{CDManagerBean.sortTitleDec}">
        <h:outputText id="decTitle" value="dec"/> 
      </h:commandLink> 
      <f:verbatim>]</f:verbatim> 
    </h:panelGroup> 
  </f:facet> 
  <h:commandLink action="#{CDManagerBean.editCD}"> 
    <h:outputText value="#{cd.title}"/> 
  </h:commandLink> 
</h:column> 

panelGroup 组件
注意一下清单 16,链接是在标题列的 header facet 中定义的。facet 只会关联一个惟一名字的组件;这样,要在 header facet 中放置一个多链接的组件,您需要使用 panelGroup。panelGroup(与 panelGrid类似)是一个单独的组件,其中包含了很多子组件。panelGroup包含两个链接,如清单 17 所示。

清单 17. panelGroup组件链接
 [listing.jsp] 
 <h:commandLink styleClass="smallLink" action="#{CDManagerBean.sortTitleAsc}"> 
    <h:outputText id="ascTitle" value="asc"/> 
 </h:commandLink> 
 ... 	
 <h:commandLink styleClass="smallLink" action="#{CDManagerBean.sortTitleDec}"> 
    <h:outputText id="decTitle" value="dec"/> 
 </h:commandLink> 

第一个链接被绑定到控制程序的 sortTitleAsc方法上,第二个链接被绑定到 sortTitleDec上。这两个方法如清单 18 所示。

清单 18. panelGroup链接方法
 [StoreController.java ] 
 /** 
 * Uses the store delegate to return 
 * a sorted list of CDs by title (ascending). 
 * 
 * @return asc 
 */ 
 public String sortTitleAsc() { 
    this.cdModel.setWrappedData(store.findTitleAsc()); 

    return "asc"; 
 } 

 /** 
 * Uses the store delegate to return 
 * a sorted list of CDs by title (descending). 
 * 
 * @return dec 
 */ 
 public String sortTitleDec() { 
    this.cdModel.setWrappedData(store.findTitleDec()); 

    return "dec"; 
 } 

这两个方法都依赖于业务代理返回一个按照正确要求排序后的 java.util.List。注意这个方法会返回逻辑输出 asc和 dec。这两个输出在 faces-config.xml 文件中都没有映射。没有映射的输出会导致重新加载当前的视图;这样,listing.jsp 将会在调用这些方法时重新进行加载,清单页面也会按照正确的顺序重新显示。
这种方法的优点是它依赖于业务代理进行排序。业务代理又可能会依赖于一个 DAO 对象,而后者又依赖于一个数据库查询或 OR 映射查询,这样可以对 CD 进行有效的查询。这种方法通常比具有一个“智能” GUI 组件的方法更好,后一种方法知道如何对随机的域对象(CD 就是一个域对象)进行排序,因为排序操作是一个经常发生的操作,严格来说,是模型的一部分(即域对象的一部分),而不是视图的一部分。
正如前面介绍的一样,对标题进行排序和对艺术家进行排序的代码几乎是相同的。作为一个练习,请自己试图为第四个使用案例编写代码,对艺术家而不是标题进行排序。
回页首
即时事件处理
我们要介绍的最后一个主题是即时事件处理。即时事件处理在您不希望(或需要)对整个页面进行有效性验证来处理用户输入的情况中非常有用。回想一下,示例程序的 cdForm.jsp 页面使用单选按钮来显示一个目录和子目录清单。当最终用户选择一个目录时,cdForm.jsp 页面就会使用 JavaScript 重新生成表单,这样就可以显示子目录清单了。
这是一个即时事件处理的例子,因为整个表单 没有在调用事件处理程序之前进行有效性验证。相反,类清单的事件处理程序会生成子目录,并强制 JSF 跳过进行响应的阶段。组件的事件处理程序通常都是在调用程序阶段执行的。即时事件组件的事件处理程序是在应用请求值阶段执行的,这发生在其余组件的类型转换和有效性验证之前。
清单 19 显示了在 cdForm.jsp 页面中再次显示的目录清单。

清单 19. cdForm.jsp 中的目录清单
 [cdForm.jsp] 
 <h:selectOneRadio id="category" value="#{CDManagerBean.cd.category}"
  immediate="true"
  onclick="submit()"
  valueChangeListener="#{CDManagerBean.categorySelected}"> 
    <f:selectItems value="#{CDManagerBean.categories}"/> 
 </h:selectOneRadio> 

selectOneRadio目录域被绑定到 CD的目录属性(value="#{CDManagerBean.cd.category}")上。注意这个即时事件处理被激活了(immediate="true")。这种设置意味着 Category组件的事件会在应用值阶段(而不是在调用程序阶段)进行处理(以及类型转换和有效性验证)。
JavaScript 功能是在 onclick="submit()"这一行 —— 即当用户进行修改时,它应该立即被提交到 Web 程序中进行处理。
事件处理程序方法
在清单中显示的可用分类是由 f:selectItems标签值(value="#{CDManagerBean.categories}")确定的。这个组件的事件处理程序的变化是控制程序的 categorySelected()方法(valueChangeListener="#{CDManagerBean.categorySelected}")。事件处理程序如清单 20 所示。

清单 20. categorySelected事件处理程序
 [StoreController.java] 
 /** 
 * Event Handler for a category getting selected. 
 * 
 * @param event event data 
 */ 
 public void categorySelected(ValueChangeEvent event) { 
    subCategoryList.setRendered(true); 

    String value = (String) event.getNewValue(); 

    if (value != null) { 
        this.subCategories = this.getSubcategoriesList(value); 
    } 

    FacesContext context = FacesContext.getCurrentInstance(); 
    context.renderResponse(); 
 } 

categorySelected()方法做的第一件事情是允许 subCategoryList调用自己。categorySelected()方法然后会使用所选择的分类值来查找一个 subCategories清单。subCategories属性被绑定到 subcategoryList值上。接下来,事件处理程序通过调用当前 FacesContext上的 renderResponse()方法强制 JSF 转到进行响应阶段。然后,GUI(cdForm.jsp)为当前显示的目录重新显示可用的子目录。
将组件绑定到控制程序上
subCategoryList组件是从 GUI 上绑定的。正如您可以将值绑定到组件上一样,您也可以将这些组件绑定到一个控制程序上。子目录是在 cdForm.jsp 页面中定义的,如清单 21 所示。

清单 21. 在 cdForm.jsp 页面中定义的子目录清单
 [cdForm.jsp] 
 <h:selectOneListbox id="subcategory" value="#{CDManagerBean.cd.subCategory}"
  binding="#{CDManagerBean.subCategoryList}"> 
    <f:selectItems value="#{CDManagerBean.subCategories}"/> 
 </h:selectOneListbox> 

binding属性允许您将 GUI 的组件绑定到后端的 bean(控制程序)上。这样,上面的组件就会被绑定到 CDManagerBean.subCategoryList上,这是在清单 22 中定义的控制程序中的一个属性。

清单 22. subCategoryList属性
 [StoreController.java ] 
 /** GUI Component that represents 
   the Subcategory list on the CDForm. */ 
 private UIInput subCategoryList; 

 { 
    subCategoryList = new HtmlSelectOneListbox(); 
 } 

 /** 
 * Subcategory list component 
 * 
 * @param aSubCategoryList The subCategoryList to set. 
 * 
 * @uml.property name="subCategoryList"
 */ 
 public void setSubCategoryList(UIInput aSubCategoryList) { 
    this.subCategoryList = aSubCategoryList; 
 } 

 /** 
 * Subcategory list component 
 * 
 * @return Returns the subCategoryList. 
 * 
 * @uml.property name="subCategoryList"
 */ 
 public UIInput getSubCategoryList() { 
    return subCategoryList; 
 } 
 
分享到:
评论

相关推荐

    NX二次开发-属性操作(创建与编辑)

    目前关于属性操作的创建于编辑主要有新旧两个版本,旧版本主要使用UF_ATTR_assign()函数,新版本主要使用UF_ATTR_set_user_attribute()函数。注意在使用新版本是需要初始化。

    编书 机械制图习题集(属性块图框)出版社.dwg

    编书 机械制图习题集(属性块图框)出版社.dwg

    毕业设计物联网实战项目基于 ESP8266 及 1.3 寸 TFT 实现的华为太空人时钟.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    【机器人控制】基于MATLAB的不同神经网络控制器性能对比:机器人手臂模型的NNPC、MRC和NARMA-L2控制策略分析(复现论文或解答问题,含详细可运行代码及解释)

    内容概要:本文档提供了三种神经网络控制器(NNPC、MRC和NARMA-L2)在机器人手臂模型上性能比较的MATLAB实现代码及详细解释。首先初始化工作空间并设定仿真参数,包括仿真时间和采样时间等。接着定义了机器人手臂的二阶动力学模型参数,并将其转换为离散时间系统。对于参考信号,可以选择方波或正弦波形式。然后分别实现了三种控制器的具体算法:MRC通过定义参考模型参数并训练神经网络来实现控制;NNPC利用预测模型神经网络并结合优化算法求解控制序列;NARMA-L2则通过两个神经网络分别建模f和g函数,进而实现控制律。最后,对三种控制器进行了性能比较,包括计算均方根误差、最大误差、调节时间等指标,并绘制了响应曲线和跟踪误差曲线。此外,还强调了机器人手臂模型参数的一致性和参考信号设置的规范性,提出了常见问题的解决方案以及性能比较的标准化方法。 适合人群:具备一定编程基础,特别是熟悉MATLAB编程语言的研究人员或工程师,以及对神经网络控制理论有一定了解的技术人员。 使用场景及目标:①理解不同类型的神经网络控制器的工作原理;②掌握在MATLAB中实现这些控制器的方法;③学会如何设置合理的参考信号并保证模型参数的一致性;④能够根据具体的性能指标对比不同控制器的效果,从而选择最适合应用场景的控制器。 其他说明:本文档不仅提供了完整的实验代码,还对每个步骤进行了详细的注释,有助于读者更好地理解每段代码的功能。同时,针对可能出现的问题给出了相应的解决办法,确保实验结果的有效性和可靠性。为了使性能比较更加公平合理,文档还介绍了标准化的测试流程和评估标准,这对于进一步研究和应用具有重要的指导意义。

    《基于YOLOv8的雪场设备识别系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    (源码)基于Python的微信智能聊天机器人.zip

    # 基于Python的微信智能聊天机器人 ## 项目简介 本项目是一个基于Python的微信智能聊天机器人框架,旨在通过ChatGPT的强大对话能力,将微信打造成一个智能助手。该机器人支持私聊和群聊的智能回复、语音识别、图片生成、插件扩展等功能,能够与好友进行多轮对话,并提供丰富的交互体验。项目支持多端部署,包括个人微信、微信公众号和企业微信应用。 ## 项目的主要特性和功能 多端部署支持个人微信、微信公众号和企业微信应用等多种部署方式。 智能对话支持私聊和群聊的智能回复,具备多轮会话上下文记忆功能,支持GPT3、GPT3.5、GPT4等模型。 语音识别可识别语音消息并通过文字或语音回复,支持Azure、Baidu、Google、OpenAI等多种语音模型。 图片生成支持图片生成和图生图功能(如照片修复),可选择DALLE、Stable Diffusion、Replicate等模型。

    Android毕设实战项目基于Android的健身信息管理系统.zip

    【项目资源】: 适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    《基于YOLOv8的医疗废物分类系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    毕业设计物联网实战项目基于腾讯云物联网开发平台的智能台灯,全套腾讯解决方案,可使用微信小程序远程控制.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    scipy-0.11.0.tar.gz

    该资源为scipy-0.11.0.tar.gz,欢迎下载使用哦!

    【机械故障仿真】PT500PLUS平行轴齿轮箱故障测试台Machine Vibration & Gearbox Simulator(机械振动-齿轮箱模拟器):转子及齿轮传动故障模拟与数据采集系统设计

    内容概要:PT500PLUS平行轴齿轮箱故障测试台是由瓦伦尼安(VALENIAN)Machine Vibration & Gearbox Simulator(机械振动-齿轮箱模拟器)开发的专业机械故障仿真测试设备。该测试台旨在模拟和研究转子、齿轮传动、轴承及电机系统中的多种常见故障,包括但不限于轴不对中、转子不平衡、机械松动、轴承故障、齿轮故障(如点蚀、磨损、断齿等)以及电机故障(如转子不平衡、轴承故障、匝间短路等)。测试台配备有先进的传感器和数据采集系统,能够实时采集并分析振动、噪声、转速、扭矩等参数,提供多通道同步信号采集与频谱分析功能。此外,测试台还配备了10寸触摸屏、PLC智能控制系统和急停按钮,确保操作简便和安全。 适用人群:机械工程专业师生、科研人员以及从事机械故障诊断和维护的技术人员。 使用场景及目标:①用于高校和科研机构的教学和研究,帮助学生和研究人员深入理解机械故障的机理;②为企业提供故障诊断和预防性维护的解决方案,提高设备可靠性和运行效率;③通过模拟真实工况下的故障,进行轴承寿命预测性试验,研究轴承故障机制与轴承载荷、转速、振动、温度之间的关系。 其他说明:测试台结构紧凑,模块化设计,便于移动和维护。它不仅支持多种传感器的安装和数据采集,还提供了丰富的分析软件功能,如FFT频谱分析、轴心轨迹图、小波分析等,支持数据导出和二次开发,适用于各种复杂的研究和应用需求。

    ### 【5G智慧文旅】商业街、水街信息集成方案:5G技术赋能全方位智慧化升级与游客体验优化

    内容概要:本文档详细介绍了XXX5G特色商业街的规划设计方案,旨在通过5G技术与物联网等前沿科技的融合,全方位提升游客体验感和街区运营效率。首先,基础信息系统涵盖综合管理智慧平台、统一结算系统、5G视频智慧安防监控系统等多个子系统,实现多系统协同管理和数据安全保障。其次,特色应用方面,推出5G短信服务、5G智慧机器人、5G无人巡逻车、5G+XR时空走廊、5G+元宇宙体验馆等项目,将尖端科技与深厚文化底蕴巧妙结合,创新文旅体验形式。最后,通过5G高清视频直播与分享、5G+高空文旅等举措,进一步提升水街的影响力和吸引力。 适用人群:本方案适用于文旅项目规划者、商业街运营管理者、信息技术从业者以及对智慧城市建设感兴趣的各界人士。 使用场景及目标:①为商业街提供全面的智慧化升级方案,涵盖基础信息系统和特色应用两大部分;②通过5G技术赋能,实现高效运营管理和沉浸式游客体验;③推动文旅产业创新发展,促进地方经济繁荣和社会进步。 其他说明:该方案不仅关注技术实现,更重视用户体验和服务质量,强调文化传承与科技创新的有机结合,致力于打造具有国际影响力的智慧文旅新地标。

    【更新至2023年】2000-2023年中国气候政策不确定性指数(全国、省、市三个层面)

    【更新至2023年】2000-2023年中国气候政策不确定性指数数据(全国、省、市三个层面) 1.时间:2000-2023年 2.来源:使用人工审计和深度学习算法MacBERT模型,基于中国《人民日报》《光明日报》《经济日报》《环球时报》《科技日报》《中国新闻社》等6家主流报纸中的1,755,826篇文章,构建了2000年1月至2023年12月的中国全国、省份和主要城市层面的CCPU指数。研究框架包括六个部分:数据收集、清洗数据、人工审计、模型构建、指数计算与标准化以及技术验证。 3.范围:中国、省、市三个层次 4.参考文献:Ma, Y. R., Liu, Z., Ma, D., Zhai, P., Guo, K., Zhang, D., & Ji, Q. (2023). A news-based climate policy uncertainty index for China. Scientific Data, 10(1), 881. 5.时间跨度:全国层面:日度、月度、年度;省级层面:月度、年度;地级市层面:月度、年度

    毕设单片机实战项目基于STM32F401和ESP8266的硬件开源物连网平台.zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    机械工程BTS200轴承寿命预测测试台Bearing Prognostics Simulator:多功能加载与润滑系统设计及应用反映了文档的核心内容

    内容概要:BTS200轴承寿命预测测试台是一款专为研究轴承寿命预测及加速磨损过程设计的实验设备。该设备结构灵活,支持不同尺寸和类型的轴承测试,最大负载可达15000N。测试台采用先进的伺服电缸加载系统,能够在轴向和径向上精确施加载荷,并配备高精度测力传感器和温度监测系统,确保实验数据的准确性。此外,BTS200还拥有油液循环润滑系统,通过油膜减少摩擦和磨损,保持机械部件在适宜的工作温度范围内,延长轴承寿命。Bearing Prognostics Simulator(实验台可通过触控屏操作,支持多速运行(0-3000RPM),并具备过热保护机制,在温度超过150℃时自动停机。BTS200广泛应用于轴承寿命预测、故障机制研究以及剩余寿命预测模型的开发。 适合人群:轴承设计研发人员、机械工程研究人员、高校实验室师生及相关领域工程师。 使用场景及目标:①研究轴承在不同载荷和转速条件下的磨损特性;②开发和验证轴承剩余寿命预测模型;③探索轴承故障机制及其对系统性能的影响;④评估不同润滑方式对轴承寿命的影响。 其他说明:BTS200测试台不仅提供硬件支持,还配备了完整的软件控制系统,包括PLC闭环控制、温度监测反馈模块等,确保实验过程的稳定性和数据的可靠性。此外,设备支持快速安装和拆卸测试轴承,便于实验操作。

    AXI Memory Mapped to PCI Express (PCIe) Gen2 v2.9

    xilinx基于PCIE IP的PCIE Bridge IP操作手册

    毕设单片机实战项目基于 STM32F407+ESP8266+RFID 的模拟公交车刷卡收费系统(物联网版).zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    使用教程 (1).mov

    使用教程 (1).mov

    (源码)基于webpack和Vue的前端项目构建方案.zip

    # 基于webpack和Vue的前端项目构建方案 ## 项目简介 本项目是基于webpack和Vue构建的前端项目方案,借助webpack强大的打包能力以及Vue的开发特性,可用于快速搭建现代化的前端应用。项目不仅完成了基本的webpack与Vue的集成配置,还在构建速度优化和代码规范性方面做了诸多配置。 ## 项目的主要特性和功能 1. 打包功能运用webpack进行模块打包,支持将scss转换为css,借助babel实现语法转换。 2. Vue开发支持集成Vue框架,能使用Vue单文件组件的开发模式。 3. 构建优化采用threadloader实现多进程打包,cacheloader缓存资源,极大提高构建速度开启热更新功能,开发更高效。 4. 错误处理与优化提供不同环境下的错误映射配置,便于定位错误利用webpackbundleanalyzer分析打包体积。

    30位最伟大的板球运动员图像集合数据集

    数据说明: 板球是世界上观看人数第二多的运动。这项运动充满了大量的情绪和戏剧性,直到比赛的最后一球。而且,有板球运动员一次又一次地证明,他们是这项运动的真正大师,改变了输掉比赛到赢得比赛的方程式,并在比赛中用他们的魔法咒语为他们的国家带来了许多胜利。作为板球迷,是时候利用深度学习技能,通过这个数据集获得更多乐趣,并检测/预测有史以来最伟大的板球运动员了。 数据准备: 2019年,BBC邀请观众投票选出“有史以来最伟大的板球运动员”,最终根据收到的最高票数发布了有史以来最伟大的30名板球运动员名单。这个数据集从中提取了30名板球运动员的相关图像6950张

Global site tag (gtag.js) - Google Analytics