`
alienj
  • 浏览: 79831 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

第8章 页面流和业务处理

阅读更多

8 页面流和业务处理

 

JBoss jBPM是一个对Java SE EE的业务处理管理引擎。 jBPM让你用一个显示等待状态、决定、任务、网页等等节点的图表显示一个业务处理或用户交互。这个图表用一个简单的、非常易读称为jPDLXML语言定义的,并且可能用eclipse插件以图形方式显示和编辑。jPDL是一个扩展语言,并适用于一系列问题,从定义网页应用程序页面流,到传统的工作流管理,以及在一个SOA(面向服务的体系结构)环境下的服务控制的所有情形。

 

Seam应用程序对两种不同问题使用jBPM

 

*定义涉及复杂用户交互的页面流。一个jPDL 处理定义定义了单个对话的页面流。一个Seam 对话被认为是与单用户相关的一个短期运行交互。

 

* 定义成拱形的业务处理。业务处理可以横越多用户多对话。它的状态被持久化在jBPM 数据库, 所以它被认为是长期运行的。 与描述一个单用户交互相比,多用户的行为调和是太复杂了,所以,jBPM为任务管理和处理多个并发执行线路提供典型的方法。

 

不要受这两种事情的困惑!它们操作在十分不同的层和粒度。页面流、对话和任务全部涉及单用户单交互。一个业务处理横越多任务。 此外,jBPM 的两种应用是完全直交的。 你能一起用它们,或者独立地使用,或者一点也不使用。

 

使用Seam你不必了解jDPL 如果你很喜欢使用JSFSeam导航控制定义页面流,并且,如果你的应用程序是过程驱动的多数据驱动,你可能不需要jBPM。但是我们发现用户交互用明确的图象表示的想法对构建强力的应用程序是很有帮助的。

 

8.1.Seam中的页面流

 

Seam中有两种方法来定义页面流:
*
JSFSeam航行控制——无状态导航模型
*
jPDL——有状态导航模型


非常简单的应用程序将只需要无状态导航模模型。非常复杂的应用程序将在不同的地方使用两种模型。每个模型都有其长处和短处!


8.1.1.
两种导航模型


无状态模型定义了来自一个命名集的一个映射,一个事件的逻辑结果直接到视窗的结果页。

 

导航控制完全无视被应用程序维持的任何状态,除了页面是事件资源。这意味着你的动作侦听器方法有时必须作出有关网页流的决定,因为只有他们能访问当前应用程序的状态。

这是一个例子,页面流定义使用JSF的导航控制:

<navigation-rule>

    <from-view-id>/numberGuess.jsp</from-view-id>

       

    <navigation-case>

        <from-outcome>guess</from-outcome>

        <to-view-id>/numberGuess.jsp</to-view-id>

        <redirect/>

    </navigation-case>

    <navigation-case>

        <from-outcome>win</from-outcome>

        <to-view-id>/win.jsp</to-view-id>

        <redirect/>

    </navigation-case>

       

    <navigation-case>

        <from-outcome>lose</from-outcome>

        <to-view-id>/lose.jsp</to-view-id>

        <redirect/>

    </navigation-case>

</navigation-rule>

 

这是一个例子,页面流定义使用Seam的导航控制:


<page view-id="/numberGuess.jsp">

       

    <navigation>

        <rule if-outcome="guess">

            <redirect view-id="/numberGuess.jsp"/>

        </rule>

        <rule if-outcome="win">

            <redirect view-id="/win.jsp"/>

        </rule>

        <rule if-outcome="lose">

            <redirect view-id="/lose.jsp"/>

        </rule>

  </navigation>

 

</page>

 

如果你发现导航控制过于冗长,你能直接从你的动用侦听器方法返回到视窗id:

 

public String guess() {

    if (guess==randomNumber) return "/win.jsp";

    if (++guessCount==maxGuesses) return "/lose.jsp";

    return null;

}

 

注意,这导致了一个重定向。你甚至能指定参数使用在重定向中:

 

public String search() {

    return "/searchResults.jsp?searchPattern=#{searchAction.searchPattern}";

}

 

有状态模型在一个命名集和逻辑应用程序状态之间定义了一个转换集。在这种模型下,用jPDL页面流定义完全地表示所有用户交互流是可能的,并且写动作侦听器方法,完全不知道交互流。

 

这是一个例子,使用jPDL 定义页面流:

 

<pageflow-definition name="numberGuess">

   

   <start-page name="displayGuess" view-id="/numberGuess.jsp">

      <redirect/>

      <transition name="guess" to="evaluateGuess">

        <action expression="#{numberGuess.guess}" />

      </transition>

   </start-page>

  

   <decision name="evaluateGuess" expression="#{numberGuess.correctGuess}">

      <transition name="true" to="win"/>

      <transition name="false" to="evaluateRemainingGuesses"/>

   </decision>

  

   <decision name="evaluateRemainingGuesses" expression="#{numberGuess.lastGuess}">

   <transition name="true" to="lose"/>

      <transition name="false" to="displayGuess"/>

   </decision>

  

   <page name="win" view-id="/win.jsp">

      <redirect/>

      <end-conversation />

   </page>

  

   <page name="lose" view-id="/lose.jsp">

      <redirect/>

      <end-conversation />

   </page>

  

</pageflow-definition>

jboss seam reference 2.1(第8章 ) - *工* - 要有光,于是就有了光

 

在这儿我们立即注意到两件事情:

 

* JSF/Seam 导航控制是很简单的。 (然而,潜在的实情是Java 代码更复杂了)

* jPDL使用户交互马上能理解,甚至不需要注意JSPJava代码。

 

另外,有状态模型更被限制。对于每一个逻辑状态(在网页流中的每一步),存在一个可能到其他状态的转换限制集。无状态模型是一个特别模型,其适合于相对不受限制、自由导航的情况,用户决定在他/她想去的下一步,而不是应用程序决定。

有状态/无状态导航的区别是非常相似于模态/非模态交互的传统观点。现在,从字面理解,Seam应用程序通常不是模态的——实事上,避免应用模态行为的主要理由之一是使用了对话!然而,Seam应用程序能是,而且往往是,模态一级的特定会话。这是众所周知,模态行为是尽量避免的事情;你的用户想要做的事情的顺序是很难预测的!但是,毫无疑问,有状态模型有它的位置。

两种模式之间最大的对比是后退按钮的行为。

 

8.1.2. Seam 和后退按钮

 

当使用JSFSeam航行控制,Seam可让用户通过后退、向前和刷新按钮自由导航。当发生这种情况时,确保对话状态维持内部一致,是应用程序的责任。组合使用Web应用框架如StrutsWebWork——不支持对话模型——和无状态组件模型如EJB无状态会话bean或者Spring框架的经验,已经告诉许多开发人员这几乎是不可能做到的!然而,我们的经验是,使用Seam上下文,那儿有一个明确的对话模式,通过有状态对话bean后退, 实际上是相当简单的。通常它是象联合在开始带空检查no-conversation-view-id的动作侦听器方法的使用一样简单。我们认为支持自由航行几乎总是令人想要的。

在这种情况下,no-conversation-view-id声明在pages.xml中。如果在一个对话期间,一个页面渲染引发了一个请求,并且对话不再存在,它会告诉Seam重定向到不同的网页:

 

<page view-id="/checkout.xhtml"

        no-conversation-view-id="/main.xhtml"/>

 

另一方面,在有状态模型, 后退按钮行为被解释为返回到以前状态的一个不确定转换。因为有状态模型执行了来自当前状态的一套转换定义,缺省时,后退按钮行为是不允许用有状态模型!Seam透明地侦测后退按钮的使用,并阻塞任何企图执行来自早先的陈旧网页的动作,并直接重定向用户到当前网页(并显示一个faces消息)。

您是否认为这一种特色或有状态模型的限制取决于你的视角:作为一个应用程序开发者,它是一个特色:作为一个用户,它可能是令人沮丧的!您可以从一个特定的网页节点通过设置back= “enabled”,启用后退按钮导航。

 

<page name="checkout"

        view-id="/checkout.xhtml"

        back="enabled">

    <redirect/>

    <transition to="checkout"/>

    <transition name="complete" to="complete"/>

</page>

 

这允许从checkout状态后退到任何早先的状态!

 

当然,如果在一个页面流期间,一个页面渲染引发了一个请求,并且用页面流的对话不再存在,我们仍需要定义发生了什么。 在这种情况下,no-conversation-view-id 声明要写入页面流定义中:

 

<page name="checkout"

        view-id="/checkout.xhtml"

        back="enabled"

        no-conversation-view-id="/main.xhtml">

    <redirect/>

    <transition to="checkout"/>

    <transition name="complete" to="complete"/>

</page>

 

在实践中,两种导航模型都有它们的位置,并且当喜欢一个模型超过另一个,你会很快学会接受它。

 

8.2. 使用jPDL页面流

 

8.2.1. 安装页面流

 

我们需要安装Seam jBPM-related组件,并放置页面流定义(使用标准.jpdl.xml扩展名)在一个Seam文档内(一个包含seam.properties文件的文档):

 

<bpm:jbpm />

 

我们也能明确地告诉Seam在什么地方找到页面流定义。我们在components.xml中指定:

 

<bpm:jbpm>

   <bpm:pageflow-definitions>

        <value>pageflow.jpdl.xml</value>

    </bpm:pageflow-definitions>

</bpm:jbpm>

 

8.2.2. 启动页面流

 

我“启动”一个基于jPDL的页面流,通过使用一个@Begin@BeginTask@StartTask注释指定处理定义名字来实现:

 

@Begin(pageflow="numberguess")

public void begin() { ... }

 

作为选择,我们能使用pages.xml 启动一个页面流:

 

<page>

        <begin-conversation pageflow="numberguess"/>

</page>

 

如果我们开始页面流,在RENDER_RESPONSE(渲染_响应)阶段期间——在一个@Factory@Create方法期间,例如——我们认为我们已在渲染的页面,并使用了一个<start-page>节点作为页面流的第一个节点,象上面的例子。

 

但是,如果页面流作为一个动作侦听器调用的结果被开始,动作侦听器的结果决定谁是被渲染的第一个页面。在这个案例,我们使用了一个<start-state>作为页面流的第一个节点,并为每一个可能的结果声明了一个转换:

 

<pageflow-definition name="viewEditDocument">

    <start-state name="start">

        <transition name="documentFound" to="displayDocument"/>

        <transition name="documentNotFound" to="notFound"/>

    </start-state>

   

    <page name="displayDocument" view-id="/document.jsp">

        <transition name="edit" to="editDocument"/>

        <transition name="done" to="main"/>

    </page>

        ...

<page name="notFound" view-id="/404.jsp">

        <end-conversation/>

    </page>

   

</pageflow-definition>

 

8.2.3. 页面节点和转换

 

每一个 <page>节点表示一个状态,等待用户输入:

 

 <page name="displayGuess" view-id="/numberGuess.jsp">

    <redirect/>

    <transition name="guess" to="evaluateGuess">

        <action expression="#{numberGuess.guess}" />

    </transition>

</page>

 

view-id JSF视窗id <redirect/>元素与其在JSF导航控制中有同样的效果:也就是,一个“传递然后重定向”行为,目的在于克服使用浏览器刷新按钮的问题 (注意,Seam越过这些浏览器重定向传播对话上下文。所以,在Seam中不需要一个Ruby on Rails样式的“flash”结构!)。

 

转换名transition name是点击numberGuess.jsp中的命令按钮或命令链接触发的一个JSF结果名。

 

<h:commandButton type="submit" value="Guess" action="guess"/>

 

当点击按钮触发转换,jBPM会调用numberGuess组件的guess()方法激活转换。注意在jPDL中指定动作使用的语法只是常见的JSF EL表达式,并且转换动作处理器只是当前Seam上下文中的Seam组件的一个方法。所以对jBPM 事件和对JSF事件我们有完全一样的事件模式。(要素一个种类原则)

 

在一个空结果的情况下(例如,一个命令按钮没有带动作定义),如果存在一个,Seam会通知转换不用名字,否则,如果所有的转换有名字,仅是重新显示这页面。所以我们能稍微简化我们的例子页面流和这个按钮

 

<h:commandButton type="submit" value="Guess"/>

 

会引发下面无名的转换:

<page name="displayGuess" view-id="/numberGuess.jsp">

    <redirect/>

    <transition to="evaluateGuess">

        <action expression="#{numberGuess.guess}" />

    </transition>

</page>

 

使用按钮调用一个动作方法是可能的,在这个情况,动作结果会决定转换执行:

 

<h:commandButton type="submit" value="Guess" action="#{numberGuess.guess}"/>

 

<page name="displayGuess" view-id="/numberGuess.jsp">

    <transition name="correctGuess" to="win"/>

    <transition name="incorrectGuess" to="evaluateGuess"/>

</page>

 

然而,这被认为是一个低等样式,因为它改变了控制页面流定义的输出流程的责任,并且返回到了其它组件。 集中关注页面流自身更好得多。

 

8.2.4.控制流

 

通常,当定义页面流时,我们不需要更加强大的jPDL的特色。可是,我们需要<decision>节点:

 

<decision name="evaluateGuess" expression="#{numberGuess.correctGuess}">

    <transition name="true" to="win"/>

    <transition name="false" to="evaluateRemainingGuesses"/>

</decision>

 

一个决定由在Seam上下文中的 JSF EL表达式产生。

 

8.2.5. 结束流

 

We end the conversation using <end-conversation> or @End. (In fact, for readability, use of both

is encouraged.)

我们结束对话使用<end-conversation> @End。(实事上,为了可读性,鼓励使用两者)

 

<page name="win" view-id="/win.jsp">

    <redirect/>

    <end-conversation/>

</page>

 

我们可选择地指定一个jBPM转换名字结束一个任务。在这个案例,Seam会发信号通知在拱型业务处理中的当前这个任务结束。

 

<page name="win" view-id="/win.jsp">

    <redirect/>

    <end-task transition="success"/>

</page>

 

8.2.6. 页面流组合

 

组合页面流,并让一个页面流暂停,同是另一个页面执行,是可能的。<process-state>节点暂停外部页面流,并开始执行一个命名页面流:

 

<process-state name="cheat">

    <sub-process name="cheat"/>

    <transition to="displayGuess"/>

</process-state>

 

在一个<start-state>节点内部流开始执行。当它达到一个<end-state>节点,内部流结束执行,并且外部流用<process-state>元素定义的转换恢复外部流执行。??<start-state>应为<process-state>吗?

 

8.3. Seam中的业务处理管理

 

业务处理是一个细粒度任务集,由用户或软件系统根据有关谁能执行一个任务和何时它应被执行的细料度规则,必须执行的一个任务集。SeamjBPM集成为用户显示任务列表很容易,并且让他们管理他们的任务。Seam也让应用程序存贮与业务处理相关的状态在BUSINESS_PROCESS上下文,并通过jBPM变量产生状态持久化。

 

一个简单的业务处理定义看起来太象页面流定义(要素一个种类原则),除用<task-node>节点代替<page>节点以外。在一个长期运行业务处理,等待状态是系统在那儿等待用户的网络操作和执行一个任务。

 

<process-definition name="todo">

  

   <start-state name="start">

      <transition to="todo"/>

   </start-state>

  

   <task-node name="todo">

      <task name="todo" description="#{todoList.description}">

         <assignment actor-id="#{actor.id}"/>

      </task>

      <transition to="done"/>

   </task-node>

  

   <end-state name="done"/>

  

</process-definition>

jboss seam reference 2.1(第8章 ) - *工* - 要有光,于是就有了光

 

在同一个项目中,我们可以有jPDL业务处理定义和jPDL页面流定义两者。如果这样,两者之间的关系是在一个业务处理中的单个<task>协调整个页面流<pageflow-definition>

 

8.4. 使用jPDL业务处理定义

 

8.4.1. 安装处理定义

 

我们需要安装 jBPM, 并告诉它在何处去找到业务处理定义:

 

 <bpm:jbpm>

    <bpm:process-definitions>

        <value>todo.jpdl.xml</value>

    </bpm:process-definitions>

</bpm:jbpm>

 

当在一个产品环境中使用Seam时,你不想每一次应用程序启动安装处理定义,可把jBPM处理当做是越过应用程序重启来持久化的。因此,在一个产品环境,你需要在Seam外面部署处理到jBPM。换言之,当开发你的应用程序时,只安装来自components.xml的处理定义。

 

8.4.2. 安装参与者ids

 

我们常常需要知道当前是什么用户在操作。jBPM通过参与者id和组参与者id“知道”用户。我们使用命名的Seam组件actor指定当前参与者id:

 

@In Actor actor;

public String login() {

    ...

    actor.setId( user.getUserName() );

    actor.getGroupActorIds().addAll( user.getGroupNames() );

    ...

}

 

8.4.3. 初始化一个业务处理

 

我们使用@CreateProcess注释,初始化一个业务处理实例:

 

@CreateProcess(definition="todo")

public void createTodo() { ... }

 

作为选择,我们能使用pages.xml初始化一个业务处理:

<page>

    <create-process definition="todo" />

</page>

 

8.4.4. 任务分配

 

当一个处理达到一个任务节点,任务实例被创建。这些实例必须指派给用户或用户组。我们能任一硬编码我们的参与者ids,或者委托给一个Seam组件:

 

<task name="todo" description="#{todoList.description}">

    <assignment actor-id="#{actor.id}"/>

</task>

 

在这个案例,我们简单地指派任务给当前用户。我们也能指派任务给一个池:

 

<task name="todo" description="#{todoList.description}">

    <assignment pooled-actors="employees"/>

</task>

 

8.4.5. 任务列表

 

几个内建的Seam组件使显示任务列表很容易。pooledTaskInstanceList是一个用户可以指派给它们自己的共享任务列表:

 

<h:dataTable value="#{pooledTaskInstanceList}" var="task">

    <h:column>

        <f:facet name="header">Description</f:facet>

        <h:outputText value="#{task.description}"/>

    </h:column>

    <h:column>

       <s:link action="#{pooledTask.assignToCurrentActor}" value="Assign" taskInstance="#{task}"/

>

    </h:column>            

</h:dataTable>

 

注意可使用简单JSF <h:commandLink>替代<s:link>

 

<h:commandLink action="#{pooledTask.assignToCurrentActor}">

    <f:param name="taskId" value="#{task.id}"/>

</h:commandLink>

 

pooledTask组件是一个内建组件,其简单地指派任务给当前用户。

 

taskInstanceListForType 组件包括指派给当前用户的特殊类型的任务:

 

<h:dataTable value="#{taskInstanceListForType['todo']}" var="task">

    <h:column>

        <f:facet name="header">Description</f:facet>

        <h:outputText value="#{task.description}"/>

    </h:column>

    <h:column>

        <s:link action="#{todoList.start}" value="Start Work" taskInstance="#{task}"/>

    </h:column>            

</h:dataTable>

 

8.4.6. 执行一个任务

 

为了开始一个任务工作,我们在一个侦听器方法上使用@StartTask @BeginTask

 

@StartTask

public String start() { ... }

 

作为选择,我们也能使用pages.xml开始一个任务工作:

 

<page>

    <start-task />

</page>

 

这些注释开始了一个特殊类型的对话,其在拱型业务处理的期间有重要意义。通过这个对话,工作能访问维持在业务处理上下文中的状态。

 

如果使用@EndTask结束对话,Seam会发信号通知任务完成:

 

@EndTask(transition="completed")

public String completed() { ... }

 

作为选择,我们能使用pages.xml

 

<page>

    <end-task transition="completed" />

</page>

 

pages.xml中,你也能使用EL指定转换。

 

在这一点上,jBPM接收并继续执行业务处理定义。(在更复杂的处理中,几个任务可能需要在处理执行恢复前被完成。)

 

为了对jBPM提供的有关管理复杂的业务处理的典型特色有更彻底地了解,请参考jBPM文档。

分享到:
评论

相关推荐

    JSP程序开发范例宝典书籍中第八章中的源代码及资料

    在本压缩包中,我们聚焦于《JSP程序开发范例宝典》一书的第八章,这是一份宝贵的学习资源,旨在为JSP(JavaServer Pages)开发人员提供实战指导和深入理解。第八章通常会涵盖特定的主题,可能是关于JSP的核心特性、...

    jsp程序开发范例宝典 第十二章

    《JSP程序开发范例宝典》第十二章聚焦于JSP(Java Server Pages)的高级应用和实战技巧。在这一章中,我们通常会深入探讨以下关键知识点: 1. **自定义标签库(Custom Tags)**:JSP 2.0引入了自定义标签库的概念,...

    Accp 5.0 ASP.Net 第八章PPT

    在 ACCP 5.0 的课程中,第八章主要讲解了如何利用第三方工具和控件来增强应用的功能和用户体验。本章涵盖了 DataList、GridView 和 Repeater 这三个常见的数据绑定控件,以及 CodeSmith、验证码控件和 FreeTextBox ...

    JSP范例宝典 第9章

    JSP是一种用于创建动态网页的技术,它允许开发者在HTML代码中嵌入Java代码,以实现服务器端的数据处理和业务逻辑。下面将对JSP的关键概念、技术和本章可能涉及的内容进行详细阐述。 1. **JSP基本概念** - JSP页面...

    Web程序设计源码(第3-10章)

    第8章:数据库连接与JDBC JDBC(Java Database Connectivity)是Java访问数据库的标准接口。这一章会讲解如何配置数据库连接池、执行SQL语句、处理结果集以及事务管理。 第9章:EJB(Enterprise JavaBeans) EJB是...

    轻量级Java EE企业应用实战第三版第二章源码

    在《轻量级Java EE企业应用实战第三版》中,第二章主要探讨了Java EE的基础概念和核心组件,以及如何构建轻量级的企业级应用程序。本章源码提供了实际操作的示例,帮助读者深入理解Java EE开发的关键技术。下面我们...

    jsp 范例宝典 第12章

    《JSP范例宝典》第12章涵盖了丰富的JSP(Java Server Pages)编程实践内容,旨在帮助读者深入理解和掌握这一动态网页技术。作为Java平台上的重要组件,JSP结合了HTML和Java代码,使得开发者能够创建交互式、数据驱动...

    轻量级Java EE企业应用实战第4版第8章01源代码.rar

    8.x文件可能包括Servlet类和JSP页面,展示了请求处理和响应生成的过程。 5. **JNDI与EJB**:Java Naming and Directory Interface (JNDI)用于查找和绑定资源,而Enterprise JavaBeans (EJB)是Java EE的组件模型。...

    Java数据库系统项目开发实践\源程序第8章.rar

    这个压缩包文件"Java数据库系统项目开发实践\源程序第8章.rar"包含了第8章的源代码,这通常意味着我们将深入学习如何在Java环境下构建一个功能完善的新闻发布平台。 在Java数据库系统项目开发中,有几个关键知识点...

    毕业论文ssm657基于spring和vue开发的web新闻流媒体平台+vue论文.doc

    第八章 总结 本论文通过设计并实现一个基于Spring和Vue的新闻流媒体平台,展示了现代Web开发技术在信息传播领域的应用,以及如何通过优化技术提高系统性能和用户体验。 第九章 致谢 对指导老师、同学及所有给予...

    轻量级Java EE企业应用实战第4版第8章02源代码

    在《轻量级Java EE企业应用实战》第四版中,第8章主要探讨了如何构建高效、可扩展且易于维护的轻量级企业应用程序。这一章的第2部分源代码涵盖了多个关键知识点,旨在帮助读者深入理解Java EE平台在实际项目中的应用...

    完全手册JSP代码_第9章

    第9章的内容可能涵盖了以上某一方面或多个方面的深入探讨,包括但不限于JSP与JavaBean的集成、JSP标签库的使用、EL表达式的应用、JSP页面优化策略等。通过学习这一章,读者可以提升对JSP技术的理解,增强开发动态Web...

    第八章JSP动态网站开发——实例.zip

    - 在动态网站开发中,JSP常与Model-View-Controller(MVC)设计模式结合,Model代表业务逻辑,View负责展示,Controller处理请求并协调Model和View。 8. JSP的现代替代品: - JSP虽然仍被广泛使用,但现代Web开发...

    Struts2.1权威指南光盘源代码第13章

    在"Struts2.1权威指南光盘源代码第13章"中,我们可以期待深入学习关于Struts2.1框架的高级特性和实践技巧。第13章通常会涵盖特定的主题,可能是框架的某个关键部分,如拦截器、结果类型、插件机制、国际化或异常处理...

    第8章 JSTL.ppt

    核心标签库(Core Tag Library)是JSTL中最基础的部分,它包含了处理变量、控制流以及URL资源访问的相关标签。 1. **变量支持标签** - `&lt;c:set&gt;`:这个标签用于设置EL(Expression Language)变量的值或修改其属性...

    Struts2.1权威指南光盘源代码第19章

    8. **Tiles框架集成**:Tiles允许创建可重用的页面片段,然后组合成完整的页面,提供了一种高效的方式来管理和构建复杂的页面结构。 9. **异常处理**:Struts2提供了全局异常处理机制,可以捕获并处理Action执行...

    Java Web开发实战宝典 第18章

    7. **文件上传与下载** - 18.10可能详细讲解了如何处理客户端的文件上传请求,以及如何提供文件下载服务,这通常涉及到HTTP协议、流处理和文件I/O。 8. **Ajax与jQuery** - 18.11可能涵盖了异步JavaScript和XML...

    秒杀系统:第9章 课程总结及重难点回顾

    前端负责用户请求的接收和页面渲染,业务逻辑层处理秒杀逻辑,数据访问层则与数据库交互,确保数据的正确存储和读取。 2. **高并发处理**: - **限流策略**:通过令牌桶或漏桶算法限制进入系统的请求速率,防止...

    Java Web整合开发实战 随盘源代码1-9章

    第8章:可能涉及安全话题,如用户认证和授权,使用HTTPS,防止SQL注入和跨站脚本攻击(XSS)。这部分内容对于开发安全的Web应用至关重要。 第9章:通常会总结前面章节的知识,并介绍一个完整的Web应用开发案例,将...

Global site tag (gtag.js) - Google Analytics