在@FacesConverter
(Primefaces 3.0)的AJAX调用期间,我对JBoss-7.1.0.CR1b的自定义p:selectOneMenu
有一个奇怪的问题。
简化的转换器看起来像这样,此类中没有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();
}
}
}
转换器用于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>
这不是火箭工程,改变后的方法只是进行调试:
public void changed()
{
logger.info("changed() "+selected);
}
但是现在讨厌的部分:changed()
从未使用上面的代码调用,但是我调用转换器三次次:
12:37:51,500 DEBUG getAsObject value: 35
12:37:51,502 DEBUG getAsObject value:
12:37:51,503 DEBUG getAsObject value:
如果我将p:selectOneMenu value="#{clientBean.selectedId}"
更改为long selectedId
并且不使用转换器,则会调用该方法一次。即使我return null
getAsObject()
changed()
被调用(一次)。我不认为它的Primefaces相关,因为如果我使用h:selectOneMenu
和f:ajax
,我会有相同的行为。
答案 0 :(得分:5)
您应该在视图中更新了<p:messages />
,<p:growl />
或<h:messages />
。您还应该注意服务器日志中有关可能缺少的消息的警告。你看到臭名昭着的Validation error: Value not valid
验证错误的机会很大。
转换后,JSF将验证提交的对象是否是可用项之一,作为防止篡改/黑客攻击请求的一部分。 JSF将submittedObject.equals(oneOfAvailableObjects)
为<f:selectItems>
中的每个可用对象执行此操作。如果没有匹配,则JSF将显示此验证错误。
在您的特定情况下,MyEjb
类显然没有equals()
方法或其实现已被破坏。另请参阅Right way to implement equals contract。