views:

370

answers:

2

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());
    }
}
+2  A: 

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"...

romaintaz
Awesome, I know that my build includes JSTL, gonna try that first.Thank you.
Filip Ekberg
I see, we are developing on Application Server 10.3 (WebLogic) from Oracle, guess we could use Facelets? Is that better?
Filip Ekberg
Facelets is really a must-have library when you develop in JSF. Which JSF version are you using ? 1.1? 1.2?
romaintaz
1.2. Is Facelets a (sun?) Java Library or some third parties?
Filip Ekberg
this is a java.net project (https://facelets.dev.java.net/). Note also that Facelets is natively integrated in the JSF 2.0 framework!
romaintaz
I see, thank you.
Filip Ekberg
Would it be possible for you to show me an example on how to use the JSF 2.0? We are using JDeveloper and can't get this to work properly. Would be a pain in the **** if we had to re-write everything :)
Filip Ekberg
Maybe it's a better thing to include Facelets in your project than using JSF 2.0, no?
romaintaz
Sure is, but is it possible to combine Facelets with JSF? Seems like i can't really manage to get that working. Would like to be able to use these in the same document: xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
Filip Ekberg
Facelets can be added to a JSF 1.2 project. Details are here: https://facelets.dev.java.net/nonav/docs/dev/docbook.html
McDowell
+1  A: 

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.

McDowell
Is it possible to have alternative row-style on lets say row_index % 2 == 0 ? I've seen that forEach has a index that you can use, but not repeater? is the datatable different in this matter?
Filip Ekberg
Yes - see the `rowClasses` attribute on the dataTable: http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/tlddocs/h/dataTable.html If you really needed the row index in a `dataTable`, you could get it by returning a `DataModel` instead of an array. See the `ArrayDataModel` class: http://java.sun.com/javaee/5/docs/api/javax/faces/model/ArrayDataModel.html
McDowell
I "only" want it to determen the current iteration. Because when i display my tabular data, i want to have an alternative row-style on every second row. Just like the <AlternativeTemplate> in ASP.NET for the Repeater control there.
Filip Ekberg
The `rowClasses` attribute is enough for that.
McDowell
Yeah figured that one out, awesome!
Filip Ekberg