Filip Ekberg
Filip Ekberg

Reputation: 36287

Binding an Object Array to a Front-End in Java Server Faces

I have a Servlet which is called upon an Action and this Servlet is suppose to return a List of Objects. Now by having the Data Structure at the end of my Post my Servlet calls the Person.fetch() which returns an list/array of Persons.

I want my Java Server Face to iterate through this list and call the getPresentation method on each object.

Is this possible and if so, how?

public class Person
{
    private String name;
    private String surname;
    private int age;

    /// -- GET --- ///
    public String getName() { return name; }
    public String getSurname() { return surname; }
    public int getAge() { return age; }

    /// -- SET --- ///
    public void setName(String name) { this.name = name; }
    public void setSurname(String surname) { this.surname = surname; }
    public void setAge(int age) { this.age = age; }

    /// -- OPERATIONS --- ///
    public String getPresentation()
    {
      return "Hi, I am " + getName() + " " + getSurname();
    }

    public Person(String name, String surname, int age)
    {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }


    /// --- STATIC METHODS --- ///
    public static Person[] fetch()
    {
        Person[] toReturn = new Person[3];
        toReturn[0] = new Person("Filip", "Ekberg", 22);
        toReturn[1] = new Person("Adam", "Sandler", 99);
        toReturn[2] = new Person("Jon", "Skeet", Math.Rand());
    }
}

Upvotes: 0

Views: 3719

Answers (2)

McDowell
McDowell

Reputation: 108859

Using core JSF, with JSPs or Facelets as the view technology, a standard way to iterate and display data is using the dataTable control. You an expression that evaluates to the array as the value attribute and set the var attribute to a string that will become the row (array entry) object. One downside of dataTable is that the renderer will only emit a table - romaintaz' suggestion of a Facelets ui:repeat would give more control.

<h:dataTable value="#{people.everyone}" var="_row">
  <h:column>
    <f:facet name="header">
      <h:outputText value="People" />
    </f:facet>
    <h:outputText value="#{_row.name}" />
  </h:column>
</h:dataTable>

Managed bean:

public class People {
  private final Person[] everyone = { new Person("Bill"), new Person("Ben") };

  public Person[] getEveryone() {
    return everyone;
  }

  public static class Person {
    private String name;
    public Person(String name) { this.name = name; }
    public Person() {}
    public String getName() { return name; }
  }
}

faces-config.xml:

  <managed-bean>
    <managed-bean-name>people</managed-bean-name>
    <managed-bean-class>people.People</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

JSTL tags (in the http://java.sun.com/jsp/jstl/core namespace) like c:forEach should not be used with JSF controls in JSPs. The mock JSTL tags in Facelets can be used, but I would avoid them if possible. Some of them tend toward evaluation at view creation time which may give unexpected behaviour. Read the docs carefully in any case.

Upvotes: 1

Romain Linsolas
Romain Linsolas

Reputation: 81587

Which JSF components libraries are you using?

You could use <c:forEach/> component from JSTL:

<c:forEach items="#{myBean.personList}" var="person">
    <h:ouputText value="#{person.presentation"/>
</c:forEach>

If you are using Facelets, you can use <ui:repeat> component. Richfaces also provide complex iteration components, such as the <a4j:repeat/> one. The principle is the same as the one used for the JSTL component, though...


Edit

As you said that you are gonna use <c:forEach> component, I suggest that you read this post about "c:forEach with JSF could ruin your day"...

Upvotes: 3

Related Questions