Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
979 views
in Technique[技术] by (71.8m points)

jsf - <f:selectItems> only shows toString() of the model as item label

I am facing a problem to populate SelectOneMenu correctly using converter. I followed several google references and lastly http://balusc.blogspot.in/2007/09/objects-in-hselectonemenu.html link of BalusC. But could not figure out the problem. I am giving all my entity, managedbean and jsf code for your consideration.

Entity:

@Entity
@Table(name = "gender")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Gender.findAll", query = "SELECT g FROM Gender g"),
    @NamedQuery(name = "Gender.findById", query = "SELECT g FROM Gender g WHERE g.id = :id"),
    @NamedQuery(name = "Gender.findByGender", query = "SELECT g FROM Gender g WHERE g.gender = :gender")})
public class Gender implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "id")
    private Short id;
    @Size(max = 10)
    @Column(name = "gender")
    private String gender;
    @OneToMany(mappedBy = "gender")
    private List<Patient> patientList;

    public Gender() {
    }

    public Gender(Short id) {
        this.id = id;
    }

    public Short getId() {
        return id;
    }

    public void setId(Short id) {
        this.id = id;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @XmlTransient
    public List<Patient> getPatientList() {
        return patientList;
    }

    public void setPatientList(List<Patient> patientList) {
        this.patientList = patientList;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set        
        return (object instanceof Gender) && (id != null) ? id.equals(((Gender) object).id) : (object == this);
    }

    @Override
    public String toString() {
        return "hms.models.Gender[ id=" + id + " ]";
    }

Converter:

@FacesConverter(value = "genderConverter")
public class GenderConverter implements Converter {

    @Inject GenderService gs;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if(value == null){
            return null;            
        }
        return gs.getGender(Integer.parseInt(value));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if(value == null) {
            return null;
        }          
        if (!(value instanceof Gender)) {
            throw new ConverterException("The value is not a valid Gender: " + value);
        }
        return ((Gender) value).getGender();
    }

}

And JSF SelectOneMenu tag:

<h:selectOneMenu id="gender" value="#{registrationBean.patient.gender}" converter="genderConverter">
                                        <f:selectItem itemValue="0" itemLabel="-- Select Gender --"  />
                                        <f:selectItems value="#{registrationBean.genderList}" />
                                    </h:selectOneMenu>

The dropdown output is similar to "hms.models.Gender[id=1]" and so on. Image sample has given below:

enter image description here

Can anybody help? Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your problem is two-fold.

Firstly, in the output the select item label is being presented, not the select item value. The converter only affects the select item value, not the select item label. Unless otherwise specified via itemLabel attribute, the select item label defaults to toString() outcome of the select item value.

Assuming that you want to display the gender property as select item label, then this should do:

<f:selectItems value="#{registrationBean.genderList}" var="gender"
    itemValue="#{gender}" itemLabel="#{gender.gender}" />

(it should be said that having a property with the same name as the class itself is quite awkward)

That should fix the presentation fail.

Secondly, you're for the output converting from Gender instance to its gender property. However, you're for the input attempting to interpret the outputted gender property as an id in order to find the associated Gender instance. This doesn't make any sense. Fix the converter accordingly to give the id back in getAsString(), exactly as expected by getAsObject().

return ((Gender) value).getId().toString();

That should fix the form submit fail.

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...