I have a weird problem with a custom @FacesConverter
with JBoss-7.1.0.CR1b during an AJAX call in p:selectOneMenu
(Primefaces 3.0).
在p:selectOneMenu(Primefaces 3.0)的AJAX调用期间,我有一个带有JBoss-7.1.0.CR1b的自定义@FacesConverter的奇怪问题。
The simplified Converter looks like this, there are no NPE or other exceptions in this class
简化的转换器看起来像这样,在这个类中没有NPE或其他异常
@FacesConverter("MyConverter")
public class MyConverter implements Converter
{
public Object getAsObject(FacesContext fc, UIComponent uic, String value)
{
logger.debug("getAsObject value: "+value);
if (submittedValue.trim().equals("")) {return null;}
else
{
MyEjb ejb = new MyEjb();
ejb.setId(Long.parseLong(value()));
return ejb; //**** alternative with return null; ****
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object value)
{
if (value == null || value.equals("")) {return "";}
else
{
MyEjb ejb = (MyEjb)value;
return ""+ejb.getId();
}
}
}
The converter is used in a p:selectOneMenu
:
转换器用于p:selectOneMenu:
<h:form>
<p:selectOneMenu value="#{clientBean.selected}" converter="MyConverter">
<f:selectItems value="#{clientBean.all}" var="my"
itemLabel="#{my.name}" itemValue="#{my}"/>
<p:ajax listener="#{clientBean.changed}" />
</p:selectOneMenu>
</h:form>
That's not rocket engineering, the changed method simply makes a debug:
这不是火箭工程,改变的方法只是进行调试:
public void changed()
{
logger.info("changed() "+selected);
}
But now the annoying part: The changed()
is never called with the code like above, but I get the converter invoked three times:
但现在讨厌的部分:使用上面的代码永远不会调用changed(),但是我调用了三次转换器:
12:37:51,500 DEBUG getAsObject value: 35
12:37:51,502 DEBUG getAsObject value:
12:37:51,503 DEBUG getAsObject value:
If I change the p:selectOneMenu value="#{clientBean.selectedId}"
to a long selectedId
and don't use the Converter the method is called once. Even if I return null
in getAsObject()
the changed()
is called (once). I don't assume it's Primefaces related, because I have the same behavior if I use h:selectOneMenu
and f:ajax
.
如果我将p:selectOneMenu value =“#{clientBean.selectedId}”更改为long selectedId并且不使用Converter,则调用该方法一次。即使我在getAsObject()中返回null,也会调用changed()(一次)。我不认为它与Primefaces相关,因为如果我使用h:selectOneMenu和f:ajax,我会有相同的行为。
1 个解决方案
#1
5
You should have a <p:messages />
, <p:growl />
or <h:messages />
which is been ajax-updated in your view. You should also pay attention to warnings in server logs about possible missing faces messages. The chance is big that you're seeing the infamous Validation error: Value not valid
validation error.
你应该有一个
, 或After conversion, JSF will validate if the submitted object is one of the available items as part of safeguard against tampered/hacked requests. JSF will do that by submittedObject.equals(oneOfAvailableObjects)
for each of the available objects as you have there in <f:selectItems>
. If nothing matches, then JSF will display this validation error.
转换后,JSF将验证提交的对象是否是可用项目之一,作为防止篡改/黑客攻击请求的一部分。 JSF将通过每个可用对象的submittedObject.equals(oneOfAvailableObjects)为
In your particular case, the MyEjb
class has apparently no equals()
method or its implementation is broken. See also Right way to implement equals contract.
在您的特定情况下,MyEjb类显然没有equals()方法或其实现被破坏。另见实施等于合同的正确方法。
#1
5
You should have a <p:messages />
, <p:growl />
or <h:messages />
which is been ajax-updated in your view. You should also pay attention to warnings in server logs about possible missing faces messages. The chance is big that you're seeing the infamous Validation error: Value not valid
validation error.
你应该有一个
, 或After conversion, JSF will validate if the submitted object is one of the available items as part of safeguard against tampered/hacked requests. JSF will do that by submittedObject.equals(oneOfAvailableObjects)
for each of the available objects as you have there in <f:selectItems>
. If nothing matches, then JSF will display this validation error.
转换后,JSF将验证提交的对象是否是可用项目之一,作为防止篡改/黑客攻击请求的一部分。 JSF将通过每个可用对象的submittedObject.equals(oneOfAvailableObjects)为
In your particular case, the MyEjb
class has apparently no equals()
method or its implementation is broken. See also Right way to implement equals contract.
在您的特定情况下,MyEjb类显然没有equals()方法或其实现被破坏。另见实施等于合同的正确方法。