JSF - 从f:param和includeViewParams创建url查询字符串的内置方法

时间:2013-05-26 03:26:26

标签: jsf viewparams

我的大多数页面导航都使用了获取请求,现在我有一个表单,其中参数应作为查询字符串参数包含在f:param内使用h:commandButton或检查includeViewParams的属性使用UIViewParameter

我不想使用includeViewParams,因为这会包含所有视图定义的参数,我只想使用作为命令组件的子项提供的参数。

<h:form>
    <p:inputText value="#{bean.value1}"/>
    <p:selectOneMenu value="#{bean.value2}"/>
    <p:commandButton action="#{utilBean.performActionParams(outcome)}">
        <f:param name="key1" value="#{bean.value1}"/>
        <o:param name="key1" value="#{bean.value2}" converter="#{bean.converter}/>
    </p:commandButton>
</h:form>

public String performActionParams(final String outcome)
{
    final UriBuilder uriBuilder = UriBuilder.fromPath(outcome);

    final FacesContext context = FacesContext.getCurrentInstance();
    final UIComponent component = UIComponent.getCurrentComponent(context);

    for (final UIComponent child : component.getChildren())
        if (child instanceof UIParameter)
        {
            final UIParameter param = (UIParameter) child;

            if (!param.isDisable() && !StringUtils.isBlank(param.getName()))
            {
                final Object value = param.getValue();

                if (value != null)
                    uriBuilder.queryParam(param.getName(), value);
            }
        }

    return uriBuilder.build().toString();
}

这个逻辑并不是很复杂,但似乎是多余的,因为它似乎与h:linkh:button中的逻辑相同。

那么有人知道这个逻辑在哪里实现了吗?

1 个答案:

答案 0 :(得分:0)

在Mojarra,这种逻辑也埋没在OutcomeTargetRenderer#getEncodedTargetURL()(和HtmlBasicRenderer#getParamList())中。 API提供的唯一公开部分是ViewHandler#getBookmarkableURL(),但它需要Map作为参数映射,而不是UIParameter组件列表。

我不确定具体的功能要求是什么,但到目前为止,您实际上似乎想要发出简单的GET请求而不是POST请求。在这种情况下,您应该使用<h:link><h:button>(或<p:button>)。它们的渲染器从内部实现此逻辑的OutcomeTargetRenderer扩展而来。你可以在outcome属性中使用EL(可能的假设是这不可能是你尝试命令按钮的原因)。

<p:button outcome="#{outcome}">
    <f:param name="key1" value="#{value1}" />
    <o:param name="key1" value="#{value2}" converter="#{bean.converter}" />
</p:button>

更新:根据评论,具体的功能要求基本上是将JSF POST表单与提交的数据一起转换为GET请求。在这种情况下,如果将输入绑定到Map已准备好在getBookmarkableURL()中使用,则会更容易。

<h:inputText value="#{bean.params.key1}" />
<h:inputText value="#{bean.params.key2}" />
<p:commandButton value="#{bean.submit(outcome)}" />

private Map<String, String> params;

@PostConstruct
public void init() {
    params = new HashMap<>();
}

public String submit(outcome) {
    // ...

    return context.getApplication().getViewHandler()
        .getBookmarkableURL(context, outcome, params, false);

    // TODO: Is faces-redirect=true also considered?
}