0

I'm trying to learn Java from a book and I've made it to the last chapter which is throwing me a bit for a loop. It shows a JSF file that contains the value expression:

#{timeBean.time}

It also shows the TimeBean.java file, which contains a getTime() method, which in turn has a variable time. The variable does not appear outside that method. The book says that #{timeBean.time} calls getTime() but I don't understand how, so I can't extend it to other applications.

For possible clarification, the problem is that I don't understand where the .time part is coming from in #{timeBean.time}

Tajha
  • 399
  • 1
  • 5
  • 15
  • 2
    I would say to first learn Java and focus on Java only by creating some console applications and probably desktop applications with Swing. After that, move to Java web application development, when you can try learning JSF. By the way, you will find plenty good resources online by hovering the mouse over the `[jsf]` tag and selecting the [info](http://stackoverflow.com/tags/jsf/info) link. – Luiggi Mendoza Sep 06 '13 at 20:02
  • 1
    @jahroy IMO it is not a good idea to mix Java learning with JSF learning since there are lot of things to learn from both sides. – Luiggi Mendoza Sep 06 '13 at 20:03
  • To answer your question, the execution of `#{timeBean.time}` is deferred evaluation expression that belongs to [Expression Language](http://stackoverflow.com/tags/el/info). The `#` is vital when working with JSF. – Luiggi Mendoza Sep 06 '13 at 20:05
  • 1
    Well, the book is about Java in general, most of which I think I've got down fairly well. It apparently decided to only have the last chapter on web applications, so now I'm trying to understand JSF, web server things (it took me two days to get GlassFish properly installed... and I haven't actually tested it yet because I'm failing to understand how the code works in JSF and such). XML was the chapter before this, and SQL the chapter before that. – Tajha Sep 06 '13 at 20:18
  • @Luiggi Mendoza Thanks for the EL link, but like I said, I'm a complete newb with this JSF stuff and I didn't really understand any of that. I checked out the link from the JSF tag, and the example there makes a little more sense to me, but makes me wonder if maybe my book is just wrong. The example there has a variable `name` which does appear outside the method, but in the example in my book `time` only appears within the method, and it isn't even the variable that's returned by `getTime()` – Tajha Sep 06 '13 at 20:22
  • 1
    First make sure the book you're reading *teachs* JSF 2 or outdated JSF 1.x, If the latter, then stop reading the book as a JSF resource. The resources you will find in StackOverflow's JSF wiki (the link I've provided before) explain how to work with JSF 2. Also, there are other good resources like mkyong's and BalusC's (JSF and Java EE expert) blogs that guide you in the JSF learning path. If you still don't really understand the concepts in the EL link, do some testing first. – Luiggi Mendoza Sep 06 '13 at 20:31

2 Answers2

2

JSF creates bean instances called managed beans, which you can call from your pages using #{} wrapped expressions, also called EL expressions. #{timeBean.time} is actually invoking getTime() getter from timeBean instance. Bean instances are referred by default with classes simple name with their first character lowercased.

So having this bean:

@ManagedBean
@RequestScoped
public class TimeBean{
    public Date getTime(){
        return new Date();
    }
}

With @ManagedBean annotation we tell JSF that it need to be managed by it. With @RequestScoped we're expressing the scope of the bean, actually JSF will create one bean instance per browser request and will call getTime() getter method, each time you specify it in your page.

For form fields, you must specify a variable which has both getter and setter methods. That's because JSF will set that value when form is processed.

@ManagedBean
@RequestScoped
public class TimeFormBean{

    //Initializes time with current time when bean is constructed
    private Date time = new Date();

    public Date getTime(){
        //No logic here, just return the field
        return time;
    }

    public void setTime(Date d){
        time=d;
    }

    public void processTime(){
        System.out.println("Time processed: " + time);
    }

}

Then you can use it in form inputs that way:

<h:form>
    <h:inputText value="#{timeFormBean.time}">  
        <f:convertDateTime pattern="yyyy-MM-dd"/>  
    </h:inputText>
    <h:commandButton value="process" action="#{timeFormBean.processTime}" />
</h:form>
Aritz
  • 30,971
  • 16
  • 136
  • 217
  • You're missing that this is a deferred expression which means it can also invoke the setter when submitting the form. – Luiggi Mendoza Sep 06 '13 at 20:07
  • True! However he didn't even mention the 'form' word in his question. – Aritz Sep 06 '13 at 20:27
  • Yes but probably OP haven't even read that part yet. Still, IMO we must provide exact info and not just part of it. – Luiggi Mendoza Sep 06 '13 at 20:27
  • I think I understand what you said... I knew the 'timeBean' part referred to the class `TimeBean`, but where does the `.time` part come from? With it being managed, does it know that the first part of the method call will be `get` or `set`, so it doesn't need those to be in the call? i.e. in a `ManagedBean` class, will the methods always be `getSomething()` and `setSomething()`, and it knows this, so when you use the EL expression, you only have to write `#{managedBean.something}`? – Tajha Sep 06 '13 at 20:33
  • @Tajha that's correct. This follows the [JavaBean API Specification](http://download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf?AuthParam=1378499822_7d655cced13e0b8a9807f54d363fcac0). By the way, *Section 8.8 in the linked document is entitled "Capitalization of inferred names" and briefly outlines how names of properties are derived* (from http://stackoverflow.com/a/1991319/1065197) – Luiggi Mendoza Sep 06 '13 at 20:35
  • @Tajha in short words, `getter` and `setter` methods are referenced without that prefix. When you call an action method you must write its entire name. – Aritz Sep 06 '13 at 20:38
  • Okay, awesome. Thanks so much, guys! I guess the book was phrasing it poorly or something. – Tajha Sep 06 '13 at 20:40
  • @Tajha you're welcome! I updated my answer again to make it clear to you! – Aritz Sep 06 '13 at 20:41
0

The concept you are looking for is called "Java Beans".

In Java, a Java Bean implements getters (also-known-as accessors) and setters (also-known-as mutators) using a specific naming convention.

It is easier for me to demonstrate that describe the naming convention.

boolean xxxBlammo;
Boolean hoot; // Note that this is not a boolean (primative).
String  smashy;  // the key is that this is not a boolean.

// convention: starts with is, first letter of property is capatalized.
public boolean isXxxBlammo() 
{
    return xxxBlammo;
}

// Note that the return type is not the primative boolean.
// convention: starts with get, first letter of prooperty is capatalized.
public Boolean getHoot()
{
    return hoot;
}

// The naming convention is the same for getSmashy as it is for getHoot.
// convention: starts with get, first letter of prooperty is capatalized.
public String getSmashy()
{
    return smashy;
}

// starts with set, first letter of property is capatalized.
public void setXxxBlammo(final boolean newValue)
{
    xxxBlammo = newValue;
}

// same naming convention for all setters.
public void setHoot(final Boolean newValue) ...
public void setSmashy(final String newValue) ...

The EL expression #{beany.smashy} references the "smashy" property of the "beany" Java Bean , which means it translates into a call to the getSmashy() getter.

In your case, #{timeBean.time} references the "time" property of the "timeBean" Java Bean, which means it translates to a call to the getTime() getter.

DwB
  • 37,124
  • 11
  • 56
  • 82