【问题标题】:Struts 2 - Understanding the working between OGNL and params interceptorStruts 2 - 了解 OGNL 和 params 拦截器之间的工作
【发布时间】:2014-01-18 03:23:16
【问题描述】:

我是 Struts 2 的新手。我正在从 Struts2 In Action 一书中学习它。我很难理解 OGNL 中的一些概念,如下 -

  1. 我们知道params拦截器将数据从请求参数移动到ValueStack中的action对象。现在在阅读时,我遇到了一句话,上面写着—— “这项工作的棘手部分是将参数名称映射到 ValueStack 上的实际属性。这就是 OGNL 的用武之地。params 拦截器将请求参数名称解​​释为 OGNL 表达式以定位正确的目的地ValueStack 上的属性”。

    问题 1) 这里的“解释”是什么意思?是 params 拦截器将请求参数转换为一些 OGNL 表达式,然后 OGNL 表达式提供到 ValueStack 中属性的映射,还是意味着其他什么?

  2. 当 result 开始其渲染过程时,Struts 2 标签通过使用 OGNL 表达式引用特定值从 ValueStack 中检索数据。

    问题2)所以标签采用OGNL表达式,但是数据是如何移动的?早些时候,params 拦截器是移动数据的拦截器,但现在没有 params 拦截器。那么数据是如何被移动的呢?

【问题讨论】:

    标签: java struts2 ognl valuestack struts2-interceptors


    【解决方案1】:

    答案#1

    参数名称是 OGNL 表达式。这是 ConventionOverConfiguraiton 的一个例子。如果我们同意使参数的名称成为可以访问 javabeans 属性的有效 OGNL 表达式,那么很容易将该名称作为表达式传递给 OGNL。这当然是在内部完成的;除非您正在破解 Struts 2 代码的那一部分,否则您实际上不需要知道它是如何工作的。

    答案 #2

    动作对象位于 ValueStack 的顶部。 ValueStack 是可用的,因为它作为 ThreadLocal ActionContext 的一部分存在,可以从在同一线程上执行的任何代码中获得。由于 Web 应用程序使用单个线程来处理请求,我们知道结果层将能够到达 ValueStack 以检索数据,再次使用标记中的名称作为 OGNL 表达式。

    注意:

    所有这一切的关键部分是 ValueStack 可用于在同一线程上执行的任何代码。这允许所有处理单个请求的代码都可以访问 ValueStack,它们可以通过 ThreadLocal ActionContext 获得(如果您不理解,请阅读 Java 的 ThreadLocal 类)。

    params 拦截器然后可以尝试使用参数名称作为 OGNL 表达式将数据写入 ValueStack(服务器作为 OGNL 上下文 - 如果您不理解,请再次阅读有关 OGNL API 的信息)。然后,处理响应呈现的 Result 类中的代码可以将标签库中的各种名称和值解释为 OGNL 表达式,以从 ValueStack 读取数据。

    【讨论】:

    • (对于 ans 2)请告诉我是否正确。标签中的名称是一个 OGNL 表达式,它在没有参数拦截器的情况下将数据从 ValueStack 移动到结果层。如果这是正确的,我无法进一步理解的是,现在 OGNL 表达式本身如何足以移动数据?我的意思是早些时候标签中也有 OGNL 表达式,但数据是由 params 拦截器移动的。
    • 我不完全理解您的评论,但我会补充我的答案以解决我认为您的担忧。
    【解决方案2】:

    假设您编写了登录页面和相应的登录操作。在页面上,您有一个文本框,其名称表明它是用户对象的名称字段。您在页面上还有一个密码字段,表示它映射到用户对象上的 pwd 字段。

    现在这里的对象图意味着它必须告诉参数拦截器名称字段实际上是登录操作中用户对象的名称字段。动作上下文、valuestack 和 OGNL 将共同拥有以下知识: 好吧,也许还有其他动作,例如 FileUploadAction。并且这些其他动作也可能具有用户对象引用。但是对于当前的操作上下文,登录页面的名称字段实际上映射到登录操作的用户对象的名称字段。它不属于 FileUploadAction 的用户对象的名称字段。 他们拥有这些知识,并且表现得好像字段本身(实际上是整个对象图)位于值堆栈上并且可以直接访问。 (稍微了解一下 ThreadLocal 的背景会更好地理解这一点。)

    拦截器是链式的,它在前进和后退的路上变成了一个责任链。一个拦截器可能会执行一些动作是前向或返回方向或两者兼而有之。所以让我们说流程如下所示:

     Page 1-->Interceptor_1--> Interceptor_2 --> Interceptor_3 -->Action_1
    

    那么返回流程如下:

    Action_1 --> Interceptor_3  --> Interceptor_2 --> Interceptor_1 --> The result Page
    

    所以,为了回答你的问题,params inteceptor 也会在返回流中被调用。

    【讨论】:

    • 但是在 params 拦截器进行任何后处理时,结果已经被渲染了。那么在任何拦截器进行后处理之前,数据是如何从 ValueStack 移动到 jsp 页面的呢?
    • 没有。在 params 拦截器进行一些后处理之前,不会呈现结果。查看突出显示的流程。渲染结果页面几乎发生在请求结束时。
    【解决方案3】:

    实际上,参数名称使用 OGNL 上下文评估为 OGNL 表达式,其中 ValueStack 是根对象。

    Here 您可以在 XWork 中找到有关 OGNL 的有用信息。对于您的问题:映射意味着在评估表达式后 OGNL 返回的上下文中不存在 null 引用。因此,表达式本身就是 OGNL 上下文抽象映射中的一个键。

    JSP 在服务器端呈现,因此无需将数据移动到客户端。但是 OGNL 表达式由 struts 标记求值,并且如果值被写入响应输出或通过用作 OGNL 表达式的键使用对对象的相同引用,则值将被复制为字符串。您还可以创建一个新键或将对象推送到值堆栈的顶部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 2023-03-31
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      相关资源
      最近更新 更多