【问题标题】:Catching global "@In attribute requires non-null value" in SEAM 2在 SEAM 2 中捕获全局“@In 属性需要非空值”
【发布时间】:2013-04-28 02:37:31
【问题描述】:

PAGE A 是一个包含数据库中一些数据的表。
通过单击一行,页面将被转发到PAGE B,并在控制器中注入实体

@DataModelSelection(value = ENTITY_LIST_NAME)
@Out(value = ENTITY_NAME, scope = ScopeType.CONVERSATION, required = false)
private Entity entity;

这可以正常工作。

问题是,我们的用户似乎使用PAGE B 的书签,所以实体永远不会被注入,因为他们从未访问过PAGE A

所以他们总是抛出这个异常

@In attribute requires non-null value

是否有一个全局函数来捕获所有@In attribute requires non-null value 异常并将用户转发到PAGE C(起始页)?
(当然我可以在PAGE B 上捕捉到这个执行,但这不仅发生在一个页面上,我们希望在每一页上处理这个异常)

我们正在使用:jboss5 + jsf 1.2 + seam 2

在 EmirCalabuch 回答后更新
我还尝试了来自 EmirCalabuch 的提示:

<page conversation-required="true" no-conversation-view-id="PageC.xhtml" />

但问题是,此时对话仍在进行中,这种转发到pageC 永远不会发生......

我也在这个页面的page.xml 中做了类似的事情:

<action execute="#{controller.checkIfEntityIsSet()}" />
<navigation>
    <rule if-outcome="HOME">
            <redirect          
             view-id="/pages/home.xhtml"
            />
        </rule>
</navigation>

在我的Controller.java 我有这样的东西:

public String checkIfEntityIsSet(){
        if(getEntity() == null){
            return "HOME"; 
        }
        return "";          
    }

但是这个checkIfEntityIsSet() 永远不会被调用,因为@In attribute requires non-null value 之前被抛出......所以这根本没有帮助......

【问题讨论】:

    标签: java jboss5.x jsf-1.2 seam2 seam-conversation


    【解决方案1】:

    异常处理规则在pages.xml 中指定。您可以包含一个规则来捕获针对该类型错误引发的org.jboss.seam.RequiredException,并执行导航到其中的页面 C。

    然而,这不是一个非常干净的解决方案,因为您会将该异常绑定到该页面,并且很可能您会在其他地方遇到此异常并希望重定向到不同的页面。

    实现相同结果的更简单方法是在PageB.page.xml 中创建所需的对话,并指定在没有对话处于活动状态时重定向到的视图。页面描述符有一个选项可以让你做到这一点(PageB.page.xml):

    <page conversation-required="true" no-conversation-view-id="PageC.xhtml" />
    

    这告诉 Seam,如果用户尝试显示页面 B 并且没有对话活动(当用户从​​书签到达那里时会发生这种情况),则将用户重定向到 PageC.xhtml。

    无论如何,使用页面参数和操作使页面可添加书签(如果您觉得您的用户会经常添加书签)只需很少的努力,例如:

    在您的列表页面 A 中,对于将您带到页面 B 的每一行,使用 s:links:button,而不是 h:commandLinkh:commandButton

    <h:dataTable var="var" value="#{myList.dataModel}">
    ...
      <s:link value="PageB.xhtml">
          <f:param name="id" value="#{var.id}" />
      </s:link>
    ...
    </h:dataTable>
    

    这将为列表中的每个实体创建一个指向页面 B 的链接,并传递其 ID(例如,第一行中的 PageB.seam?id=1,第二行中的 PageB.seam?id=2,依此类推。这些链接是可收藏的。

    PageB.page.xml上声明参数:

    <param name="id" value="#{myHomeComponent.id}" />
    

    其中myHomeComponentEntityHome&lt;YourEntity&gt; 类型的组件。然后,您可以在页面 B 中使用 #{myHomeComponent.instance} 来访问选定的实体。

    【讨论】:

    • 嗨,EmirCalabuch,我已经更新了这个问题......感谢您的帮助,但它没有奏效,请阅读上文了解更多详情!
    • 很可能您在页面 B 中有一个begin-conversation,或者您用来调用页面 B 的链接中包含对话 id 参数。
    • 我在pageB.page.xml 中使用或不使用begin-conversation 都试过了 - 但它不起作用。问题是,不管有没有对话,@In 总是空的,这会导致错误。
    【解决方案2】:

    我现在管理它不同:

    Controller.java 中我有这样的初始化:

    @Create
    public void initialize() throws MissingMyEntityException {
    
        if(qualifiedCustomer == null){
            throw new MissingMyEntityException("something wrong");
        }
        ....
    }
    

    我的MissingMyEntityException.java 看起来像这样:

    public class MissingMyEntityException extends Exception {
    
        private static final long serialVersionUID = 8640645441429393157L;
    
        public MissingMyEntityException(String message) {
            super(message);
        }
    
    }
    

    pages.xml 我有这样的异常处理程序:

    <exception class="com.dw.companyName.view.xyz.exception.MissingMyEntityException">
            <redirect view-id="/pages/home.xhtml">
                <message>something went wrong</message>
            </redirect>
        </exception>
    

    这解决了问题。
    但是感谢您的帮助,但它没有按照您的方式工作:(

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 2017-03-11
      相关资源
      最近更新 更多