2

我有两个<f:viewParam>标签包含在<f:metaData>JSF 页面上的标签中,如下所示。

index.xhtml 文件:

<h:form id="form" prependId="true">
    <f:metadata>
        <f:viewParam name="userId" id="paramId" rendered="#{not empty param.userId}" converter="#{userRoleConverter}" value="#{testManagedBean.userTable}"/>                
        <f:viewParam name="userRoleId" id="userParamId" rendered="#{not empty param.userRoleId}" converter="#{userAuthorityRowSelectionConverter}" value="#{testManagedBean.entity}"/>
        <f:event type="preRenderView" listener="#{testManagedBean.preRenderEvent}" />
    </f:metadata>
    <p:messages id="messages" globalOnly="false" showDetail="true" showSummary="false" autoUpdate="false" closable="true"/>
</h:form>

converter它们中的每一个都与属性指定的转换器相关联。

当两个参数即userIduserRoleId作为查询字符串附加到 URL 时,两个属性即userTableentity被设置为关联的托管 bean -testManagedBean在指定的转换器进行转换之后。

托管bean:

@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable
{
    private UserRoles entity;    //Both are POJOs.
    private UserTable userTable;

    public TestManagedBean(){}

    //Setters and getters of both the properties entity and userTable.        

    public void preRenderEvent(ComponentSystemEvent event) throws AbortProcessingException
    {
        System.out.println((entity==null)+" : "+(userTable==null));
    }
}

当其中一个属性的转换失败时,或者userIduserRoleId,另一个属性以及失败的属性也不会设置为托管 bean(预计会设置,因为该其他属性的转换不太可能失败)并且两者其中为空。

例如,如果我输入了这样的 URL,

/index.jsf?userId=100&userRoleId=12

然后,方法中的以下语句preRenderEvent()(与 关联<f:event>),

System.out.println((entity==null)+" : "+(userTable==null));

显示true : true.

在这种情况下,转换userId失败(数据库中不存在值 100)但转换userRoleId应该成功(但没有成功)并且不应该为空(存在于数据库中)。


同样,以下网址,

/index.jsf?userId=1&userRoleId=120

再次显示true : true

这是前一个的相反情况。userId存在于数据库中,但userRoleId不存在。


最后,以下网址,

/index.jsf?userId=1&userRoleId=12

显示false : false。在这种情况下,两个参数的值都存在于数据库中它们各自的表中。

转换失败通过抛ConverterException来通知就不用说了。


那么,当其中一个属性的转换失败时,为什么这两个属性的值都设置为 null?当其中一个转换器的转换失败时,是否只执行其中一个转换器?

4

1 回答 1

1

您不应该使用转换器来验证,而应该使用验证器。null如果找不到任何内容,则让转换器返回(并且ConverterException仅当值不能解释为用户 ID 时才抛出,即它是不可转换的)。如果required="true"您希望该值为非null.

例如

if (value == null) {
    return null;
}

if (!value.matches("[0-9]+")) {
    throw new ConverterException("Supplied parameter value can't be interpreted as an user ID.");
}

return service.getById(Long.valueOf(value)); // May return null if it doesn't exist.

顺便说一句,该rendered属性在那里没有任何意义<f:viewParam>。那是构建 JSF 组件树的标记处理程序,而不是呈现一些 HTML 的 UI 组件。更重要的是,它根本没有记录<f:metadata>此外,看到嵌套在表单中有点奇怪。参考当使用 <ui:composition> 模板时,我应该在哪里声明 <f:metadata>?

于 2013-09-02T16:25:15.787 回答