【问题标题】:struts2 prepare and validationstruts2 准备和验证
【发布时间】:2012-04-27 09:09:24
【问题描述】:

我试图确保在调用操作时给出预期的参数(比如显示用户配置文件我想确保参数包含用户 ID:viewUser.action?userId=1 应该可以正常工作,但 viewUser .action 应该重定向到错误页面)

所以我创建了一个验证 xml,指定 userId 字段不能为空。一切正常。

但是现在,在 prepare() 上,我使用 userId 做了一些准备工作。 事实是在验证拦截器之前调用了准备拦截器,因此如果 userId 为 null,那么我有一个很好的 nullPointerException 并且不会调用验证,因为之前发生了错误。 我知道我可以切换拦截器顺序,但我不想这样做。

所以我的问题是: 我应该在 prepare() 方法中使用参数吗?有没有其他方法可以处理?

感谢和抱歉我的英语不好:(

【问题讨论】:

    标签: validation parameters struts2 interceptor prepare


    【解决方案1】:

    使用“paramsPrepareParamsStack”拦截器堆栈。

    【讨论】:

    • 所以我将有参数 => 准备 => 参数 => 验证。但是如果 idUser 为空,我仍然会在准备中使用 idUser 时遇到问题。
    • @Estragon 你不能检查它是否为空?或者您使用它的业务逻辑没有进行任何健全性检查?
    • 我当然会检查所有输入,但我不认为准备是检查的地方,验证系统应该比手动检查准备/业务功能更好......而且我真的不知道如何如果准备中的参数为空,则做出反应
    • @Estragon 所以,你不想改变拦截器的顺序,也不想手动检查。听起来你运气不好。
    • 好吧,他的另一个选择是改变他对问题的看法,因此不需要 paramsPrepareParamsStack,这可能值得了解,但也是最长的路。
    【解决方案2】:

    您可以在 struts-default.xml 文件中更改拦截器的默认顺序,因此复选框和参数拦截器将在准备拦截器之前启动。

    <interceptor-stack name="basicStack">
      <interceptor-ref name="exception"/>
      <interceptor-ref name="servletConfig"/>
      <interceptor-ref name="checkbox"/>
      <interceptor-ref name="params"/>
      <interceptor-ref name="prepare"/>
      <interceptor-ref name="conversionError"/>
    </interceptor-stack>
    

    但我不喜欢这个主意。我认为更好的方法是更改​​您的操作逻辑并从准备函数中删除所有代码部分(如果它们使用某些参数)。为什么你在“准备”中这样做?您想在验证期间使用结果吗?

    【讨论】:

    • prepareParamsPrepareStack 已为此目的而存在;为什么要自己做?除此之外,OP 已经声明无论出于何种原因切换拦截器顺序都是不可取的。
    • 啊,你的意思是paramsPrepareParamsStack?是的,这是更好的解决方案。
    • 哎呀,是的——把那些倒过来了,我一定是在中间的 30 分钟内忘记了;)
    • @Estragon “另外,如果准备中的参数为空,我真的不知道如何反应”。 1. 这次在你的操作中使用验证函数,而不是validation.xml。 2.从准备到验证中删除idUser的所有逻辑(如果你想在“执行”之前执行它)。 3 如果您在验证过程中发现 idUser 存在问题,请使用 addFieldError("idUser", "idUser error message")
    【解决方案3】:

    以下是关于如何避免此问题并使所有开发变得更容易的解释,但最直接的解决方案无疑是 Daves。我肯定会首先实施该问题并解决该问题并在将来使用以下内容。

    根据我的经验,prepare() 用于获取服务,这将使操作完成它的工作,而依赖注入 (Spring) 可以提供最好的服务。

    一般而言,动作类负责以下工作:

    • 获取执行操作所需的对象(服务对象)。
    • 获取执行操作所需的参数(服务对象用于获取我们需要的参数)。
    • 验证参数是否有意义(验证方法/注释,可以外部化到 xml)。
    • 执行操作(使用前面提到的服务对象)。
    • 获取视图所需的对象...

    您知道这一点,您也知道 prepare 是关于获取执行操作所需的对象(理想情况下是服务对象,尽管有些人会做诸如打开数据库连接之类的事情)。实际做的应该仅限于execute方法。

    采用理想的路线,即使用通过您选择的 DI 提供者(Spring/Guice)注入的服务对象,我们发现自己几乎没有理由需要 prepare 方法。结果,我们的动作变得更小、更容易理解和更容易测试。

    【讨论】:

      猜你喜欢
      • 2014-05-17
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多