0

I'm really new to JSF, I've been learning it exactly 2 days now. Besides the initial confusion about the concepts, I have issues with eclipse too. I'm using JSF 2.0 with obviously Eclipse and Tomcat 7.

Firstly, let me describe what I'd want to do: in scope of learning the JSF I want to have a User class, with name, surname, age and Id. Then, I'd like to list pre-defined users and add a submit form. Besides that, there's also a "user detail" option.

Here's my code:

User class:

package com.tutorial;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class User {

private String name;
private String surname;
private int age;
private int id;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

public String getSurname() {
    return surname;
}
public void setSurname(String surname) {
    this.surname = surname;
}

public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

public User(String name, String surname, int age, int id) {
    super();
    this.name = name;
    this.surname = surname;
    this.age = age;
    this.id = id;
}

public User(){}
}

Users "bean":

package com.tutorial;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@SessionScoped
public class UsersBean {

private List<User> listOfUsers = new ArrayList<User>();
private String passedParameter;

public UsersBean()
{
    listOfUsers.add(new User("Tywin", "Lannister", 60, 1));
    listOfUsers.add(new User("Tyrion", "Lannister", 30, 2));
    listOfUsers.add(new User("Jaime", "Lannister", 31, 3));
}
public List<User> getAll()
{

    System.out.println("Called!");
    return listOfUsers;
}

public User getDetails()
{
    passedParameter = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("userID");
    int id = Integer.parseInt(passedParameter);
    User selected = null;
    for (User u : listOfUsers)
    {
        if (u.getId() == id)
        {
            selected = u;
        }
    }
    return selected;
}

public void addUser(User u)
{
    u.setId(listOfUsers.size()+1);
    listOfUsers.add(u);
}
}

users.xml (partial code):

    <f:view>
        <!-- http://stackoverflow.com/questions/8083469/method-must-have-signature-string-method-etc-but-has-signature-void -->
        <h:dataTable value="#{usersBean.all}" var="u">
        <h:column>
            <f:facet name="header">
                User ID
            </f:facet>
                #{u.id}
        </h:column>
        <h:column>
            <f:facet name="header">
                Name
            </f:facet>
                #{u.name}
        </h:column> 
        <h:column>
            <f:facet name="header">
                Details
            </f:facet>
            <h:link outcome="usersDetails" value="get details">
                <f:param name="userID" value="#{u.id}"></f:param>
            </h:link>
        </h:column>     
        </h:dataTable>

        <h:form>
            <h:outputText value="Name"></h:outputText>
            <h:inputText value="#{user.name}"></h:inputText>
            <h:outputText value="Surname"></h:outputText>
            <h:inputText value="#{user.surname}"></h:inputText>
            <h:outputText value="Age"></h:outputText>
            <h:inputText value="#{user.age}"></h:inputText>
            <h:commandButton action="#{usersBean.addUser(user)}" value="Add" type="submit"></h:commandButton>
        </h:form>

    </f:view>

And finally, usersDetails.xhtml (partial code as well):

<ui:define name="content">
<ui:param name="user" value="#{usersBean.details}" />
    <h:outputText value="#{user.name}"></h:outputText>
    <h:outputText value="#{user.surname}"></h:outputText>
    <h:outputText value="#{user.id}"></h:outputText>
</ui:define>

OK, now the questions:

(1) in users.xhtml (see code above - usersBean.all in datatable), it appears as if this function gets called as many times as there are values in arraylist. The "System.out.println("Called!")" is written as many times as there are values in arraylist. Have I done something wrong? I don't believe it's suppose to be called for each object in arraylist.

(2) in users.xhtml, this part of the code

<h:commandButton action="#{usersBean.addUser(user)}" value="Add" type="submit"></h:commandButton>

is highlighted by eclipse and it reads: "Method must have signature "String method(),..." Did I call the method the wrong way? Is there an alternative to send object to the UsersBean's addUser function? What would be correct way if Eclipse defines this as wrong?

Thank you very much for your time and answers!

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555

1 Answers1

0

1) In JSF, method (used for bulding view) can be called more than once. For proper testing you can create user list with 20 or more users and check again how many times getAll method will be called. I think it still be the same number (3 in your case).

2) Action method in JSF should return redirection outcome (with type String). It is reason why you have message about "signature String method". Change signature of addUser method from public void addUser(User u) to public String addUser(User u) and return outcome for navigation to new page or null for stay on the same page.

Vasil Lukach
  • 3,658
  • 3
  • 31
  • 40
  • You're absolutely right, I have now 5 users in the list and it's called 3 times. Can you please elaborate why is the method called 3 times if I explicitly call it only once? – user3588536 May 18 '14 at 17:26
  • See [Why JSF calls getters multiple times](http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-timesV) – Vasil Lukach May 18 '14 at 23:57