验证错误:值无效

时间:2013-01-23 03:11:45

标签: jsf-2 primefaces

我遇到过我写过的客户转换器的问题。我从转换器调用我的DAL并将其作为托管属性注入。当我从我的一个ui组件调用转换器时,一切正常;但是当我从另一个组件调用它时,注入的DAL为空。如果这是一个骗局我道歉,我已经到处寻找答案了。

我正在使用primefaces 3.5。

这是转换器:

@ManagedBean(name = "fanlistConverter")
public class FanlistConverter implements Converter, Serializable {
private  List<Fanlist> fanlist; 
@ManagedProperty(value="#{dAL}")
private DAL dAL;
private static Session session;


public FanlistConverter(){

} 

@PostConstruct
public void init(){
    session  = dAL.getSession();

}




public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {  
    if (!submittedValue.equals(null) &&  !submittedValue.equals("null")) {  
        Fanlist fanlist = new Fanlist();

        try {  

                fanlist = (Fanlist)session.get(Fanlist.class, UUID.fromString(submittedValue));


            } catch(NumberFormatException exception) {  
                System.out.println("error: " + exception.getMessage());
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid player"));  
            }catch(Exception e){
                System.out.println("error get as Object: " + e.getMessage());

            }


    } 

   return  fanlist; 


}  

 public String getAsString(FacesContext facesContext, UIComponent component, Object value) {  
        if (value == null || value.equals("")) {  
            return "";  
        } else {  
            return String.valueOf(((Fanlist) value).getId());  
        }  
    }   



public DAL getdAL() {
    return dAL;
}

public void setdAL(DAL dAL) {
    this.dAL = dAL;
}  

}

以下是两个ui组件

这个有效:

                <p:panelGrid columns="3">
                    <p:outputLabel for="fanlist" value="Subscription Opt-In List    " />
                    <p:autoComplete id="fanlist" dropdown="true"
                        value="#{campaignWizard.selectedList}"
                        completeMethod="#{campaignWizard.complete}" var="f"
                        itemLabel="#{f.name}" itemValue="#{f}" converter="#{fanlistConverter}" />
                    <p:commandLink value="Add List"
                        actionListener="#{campaignWizard.addFanList}" update=":formbox2"
                        ajax="false" />
                </p:panelGrid>

而且这个不起作用

        <p:selectManyMenu id="fanlist2" value="#{blast.selectedLists}"
                    var="fl" showCheckbox="true" converter="#{fanlistConverter}"
                    style="width:250px;height:100px">
                    <f:selectItems value="#{blast.fanlists}" var="fanl"
                        itemLabel="#{fanl.name}" itemValue="#{fanl}" />
                    <p:column>
                        Name: #{fl.name} 
                        </p:column>
                    <p:column>
                        Size: #{fl.name}
                        </p:column>
                </p:selectManyMenu>




@ManagedBean(name = "blast")
@ViewScoped
public class BlastBean implements Serializable {
@ManagedProperty(value="#{globalVars}")
private GlobalVars globalVars; 

@ManagedProperty(value="#{dAL}")
private DAL dAL;

@ManagedProperty(value="#{messaging}")
private Messaging messaging; 

private User u; 
private Blast blast;
private List<Fanlist> fanlists; 
private List<Fanlist> selectedLists;
private List<Fanlisttoparent> fltops = new ArrayList<Fanlisttoparent>();

    public  BlastBean(){


}

@PostConstruct
public void init(){

    fetchData();


}

public void fetchData(){
    u = globalVars.getUser();
    blast = new Blast();
    fanlists = dAL.query("FROM Fanlist where client.id ='" + globalVars.getUser().getClient().getId() + "'");

}   

...

public String sendBlast(){
    System.out.println("blast:" + blast.getMessage());
    dAL.upsert(blast);
    final List<String> phoneNumbers = new ArrayList<String>(); 

    List<Profile> profiles = new ArrayList<Profile>(); 
    for(Fanlist fl: selectedLists){
        Set<Fantolist> fantolist = fl.getFantolists();
        for(Fantolist ftol: fantolist){
            profiles.add(ftol.getFanprofile().getProfile());
        }

        for(Profile p: profiles){
            phoneNumbers.add("+1"+ p.getPhonenumber());
        }

    }



...

1 个答案:

答案 0 :(得分:1)

首先,我们需要了解何时会发生Validation Error: Value is not valid。如果当前所选项目的equals()测试未针对任何当前可用的项目返回true,则会发生此错误。

因此,此错误在技术上有两个原因:

  1. 项目类型的equals()方法丢失或损坏。
  2. 与初始请求相比,当前可用项目列表的更改不相同。

    当涉及转换器时,则有第三个原因:

  3. 转换器已返回null而不是getAsObject()中的所需对象。

  4. 根据目前提供的信息,转换器可在一页中正常工作,但在其他页面中则无效。因此原因1可以安全地划伤。留下原因2和3.

    对于原因2,您需要保证在处理表单提交期间<f:selectItems value="#{blast.fanlists}">不会返回不同的值。如果#{blast} bean是请求范围的,并且fanlists属性是基于在表单提交期间丢失的某个请求范围变量初始化的,则可能发生这种情况。您可以通过将bean放在视图范围内来确定它(并确保您没有在getter中执行业务逻辑)。

    至于原因3,调试器/记录器应该提供足够的线索,说明转换器是否正常工作。这个问题实际上超出了JSF的范围。开发人员有责任根据提交的值返回正确的对象实例。

    另见:


    对具体问题

    无关。转换器上的@FacesConverter注释是超级的。它没有在这个结构中使用。如果您已经使用过它,那么根本不会注入托管属性。另见其他How can I inject in @FacesConverter?