gpt4 book ai didi

java - f :viewParam with Converter and ViewScoped exception out when invoke the second ajax request

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:53:45 24 4
gpt4 key购买 nike

我有这个 f:viewParam,我尝试绑定(bind)验证并将 userId 转换为 Player,我得到了一个 意外的结果。

<f:metadata>
<f:viewParam name="userId" value="#{myBean.selectedPlayer}" converter="pConverter"
converterMessage="Bad Request. Unknown User" required="true"
requiredMessage="Bad Request. Please use a link from within the system" />

</f:metadata>
<h:body>
<p:messages id="msgs"/>
<h:form>
<ul>
<li><a href="index2.xhtml?userId=1">Harry</a></li>
<li><a href="index2.xhtml?userId=2">Tom</a></li>
<li><a href="index2.xhtml?userId=3">Peter</a></li>
</ul>
</h:form>
<h:form>
<h:panelGrid columns="2" rendered="#{not empty myBean.selectedPlayer}">

<h:outputText value="Id: #{myBean.selectedPlayer.id}"/>

<h:outputText value="Name: #{myBean.selectedPlayer.name}"/>

</h:panelGrid>
</h:form>
<h:form id="testForm">
<h:inputText value="#{myBean.text}"/>
<p:commandButton value="Switch" update=":msgs testForm"/>
<h:outputText value="#{myBean.text}" rendered="#{not empty myBean.text}"/>
</h:form>
</h:body>

我的转换器看起来像这样

@FacesConverter(value="pConverter")
public class PConverter implements Converter {
private static final List<Player> playerList;
static{
playerList = new ArrayList<Player>();
playerList.add(new Player(1, "Harry"));
playerList.add(new Player(2, "Tom"));
playerList.add(new Player(3, "Peter"));
}

@Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value == null || !value.matches("\\d+")){
return null;
}
long id = Long.parseLong(value);
for(Player p : playerList){
if(p.getId() == id){
return p;
}
}
throw new ConverterException(new FacesMessage("Unknown userId: " + value));

}

@Override
public String getAsString(FacesContext fc, UIComponent uic, Object value) {
if(!(value instanceof Player) || value == null){
return null;
}
return String.valueOf(((Player)value).getId());
}
}

当我单击三个链接(Harry、Tom、Peter)时,转换器运行良好。它转换 id 并将 player 绑定(bind)回我的托管 bean。然后我在文本框中键入一些内容,然后单击 Switch,第一次它工作正常,我键入的内容出现在按钮旁边,但随后我更改了我键入的内容,然后单击 Switch ,然后出现错误消息 Bad Request.请使用系统内的链接,这是 f:viewParamrequired 的错误消息。如果我将 f:viewParam 取出,那么一切正常。令人惊讶的是,如果我从 f:viewParam 切换到 o:viewParam (OmniFaces),那么它工作得很好。

最佳答案

那是因为 <f:viewParam>在每个 HTTP 请求上运行,也在回发上运行。它在您的情况下适用于普通 GET 链接,因为您在链接中传递的正是该参数。对于 POST 表单,它失败了,因为您没有在按钮中传递该参数。所以它变成了null在请求参数映射和 required validator 启动,因此出现此验证错误。

为了保持<f:viewParam required="true">对 POST 表单也很满意,您基本上需要通过 <f:param> 保留初始请求参数在命令按钮/链接中。

<p:commandButton value="Switch" update=":msgs testForm">
<f:param name="userId" value="#{param.userId}" />
</p:commandButton>

OmniFaces <o:viewParam> ,旨在与 View 作用域 bean 结合使用,在 isRequired() 中进行了额外检查 setter/getter (source code here):

@Override
public boolean isRequired() {
// The request parameter get lost on postbacks, however it's already present in the view scoped bean.
// So we can safely skip the required validation on postbacks.
return !FacesContext.getCurrentInstance().isPostback() && super.isRequired();
}

所以,这会跳过 required每个回发的 validator (此外,由于其无状态的性质,它还会跳过在每个回发上设置模型值)。这就是为什么您看不到验证错误并且您仍然拥有正确的模型值(不会在每次回发时重置)。

关于java - f :viewParam with Converter and ViewScoped exception out when invoke the second ajax request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10526431/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com