@FacesConverter阻止p:selectOneMenu和p:ajax的方法调用

时间:2023-01-26 20:02:12

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.

你应该有一个

,你的视图中已经更新了ajax。您还应该注意服务器日志中有关可能缺少的消息的警告。您看到臭名昭着的验证错误的机会很大:值无效的验证错误。

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)为 提供。如果没有匹配,则JSF将显示此验证错误。 :selectitems>

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.

你应该有一个

,你的视图中已经更新了ajax。您还应该注意服务器日志中有关可能缺少的消息的警告。您看到臭名昭着的验证错误的机会很大:值无效的验证错误。

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)为 提供。如果没有匹配,则JSF将显示此验证错误。 :selectitems>

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()方法或其实现被破坏。另见实施等于合同的正确方法。