自定义转换器 - 依赖selectonemenu未填充

时间:2015-11-02 12:37:40

标签: jsf jsf-2.2 selectonemenu

我尝试设置两个selectOneMenus,其中第一个选择一个对象,在第二个中,可以选择五个对象参数中的一个。为此,我构建了一个自定义转换器,“id”应该从第一个selectOneMenu传递到第二个菜单的uniqely标识对象。在页面加载时,调用getAsString方法并迭代第一个菜单的所有项目。在选择项目时,会调用getAsObject,并使用正确的id并返回正确的Question。但是:第二个菜单根本没有填充。我错过了什么?帮助赞赏,我还在学习这个。

这是第一个selectOneMenu:

<h:selectOneMenu converter="answerDeliverer">
    <f:selectItems value="#{questionBean.list}" var="question" itemValue="#{question}" itemLabel="#{question.text}"/>
    <f:ajax event="change" render="answers"></f:ajax>
</h:selectOneMenu>

第二个:

<h:selectOneMenu id="answers">
    <f:selectItem itemValue="1" itemLabel="#{question.a1}"/>
    <f:selectItem itemValue="2" itemLabel="#{question.a2}"/>
    <f:selectItem itemValue="3" itemLabel="#{question.a3}"/>
    <f:selectItem itemValue="4" itemLabel="#{question.a4}"/>
    <f:selectItem itemValue="5" itemLabel="#{question.a5}"/>
</h:selectOneMenu>

转换器:

@ManagedBean (name = "answerDeliverer")
@RequestScoped
public class answerDeliverer implements Converter {

    @EJB
    private QuestionDAO questionDAO;

    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
        return questionDAO.get(Integer.parseInt(s));
    }

    @Override
    public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
    if (o instanceof Question) {
        return ((Question) o).getId();
    } else if (o instanceof String) {
        return ((String) o);
    } else throw new ConverterException(new FacesMessage(o + " is not a valid Question or id"));
    //just so I can try either question or question.id as itemValues
}

}

错误日志为空,仅在启动时我收到此类警告:

Unknow type constant pool 18 at position 7
Nov 03, 2015 1:17:10 PM com.sun.faces.config.JavaClassScanningAnnotationScanner$ConstantPoolInfo containsAnnotation

经过几个小时的调试,我现在陷入了困境。我可以得出以下结论:

  • answerDeliverer似乎有效。在选择时,getAsObject从数据库中提取正确的question
  • XHR在每个选择中以浏览器调试模式注册,并且“200 OK”服务器应答
  • 日志中没有其他错误
  • 我将question带入第二个selectOneMenu的范围似乎有问题。 Question不是ManagedBean,而是QuestionBeanprivate Question question = new Question(),所以,无论我在第一个selectOneMenu中做什么,第二个总是生成一个新实例并不关心我以前做过什么?从而抹去了我以前的任何question?我怎么能避免这个?

我在Tomcat 8上使用Mojarra-2.2.1。还尝试使用OmniFaces,但在放弃之前陷入无限循环调试设置。

如果有任何帮助,我会添加Question POJO和Bean。

public class Question implements Serializable {
    private String text;
    private String a1 = Constants.defaulta1;
    private String a2 = Constants.defaulta2;
    private String a3 = Constants.defaulta3;
    private String a4 = Constants.defaulta4;
    private String a5 = Constants.defaulta5;
    private String id;
    private String nodeid;
    //getters and setters
    @Override
    public boolean equals(Object other) {
        return (other != null && getClass() == other.getClass() && id != null)
                ? id.equals(((Question) other).id)
                : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null)
                ? (getClass().hashCode() + id.hashCode())
                : super.hashCode();
    }

    @Override
    public String toString() {
        return id;
    }
}

QuestionBean

@ManagedBean (name="questionBean")
@ViewScoped
public class QuestionBean implements Serializable {
    private List<Question> list;

    //this was for a CRUD page; I deleted the other irrelevant code
    private Question question = new Question();
    private boolean edited;

    @EJB
    private QuestionDAO questionDAO;

    @PostConstruct
    public void init() {
        list = questionDAO.getAll();
    }

    public List<Question> getList() {
        return list;
    }

    public Question getQuestion() {
        return question;
    }

}

0 个答案:

没有答案