I am trying to run an example in chapter 7 of JavaServer Faces 2.0: The Complete Reference by Ed Burns, and am running into trouble. It formats a little web page with an input field, a button, and an output field. When you type something in the input field and then click the button, the text entered is supposed to be echoed in the output field.
The example uses a backing bean to accomplish this. The bean has an action method (to which the button is bound) which not only updates the output field, it also makes the input field readonly. The odd thing is that the readonly attribute changing part works OK. The part that isn't working is the updating of the output field.
Here is the code.
First, the xhtml file, which I have called register.xhtml:
Then the backing bean source code, Hello.java:
And the web-xml:
And the faces-config.xml file:
I'm using Maven to compile this (with command mvn clean install). Here is the pom.xml file:
I think that's everything, but if you need any further code or information to help me resolve this, please post! Thanks.
An IDE is no substitute for an Intelligent Developer.
Joined: Jul 23, 2009
Nothing's "wrong" with it (in a cosmically ethical sense), but it doesn't appear to work, and isn't really in the spirit of the exercise.
When I substituted your code for the hutputText component that I had, I got a NullPointerException when running the website. I was able to avoid the exception by commenting out the "outputText1.setValue(inputText1.getValue())" in the commandButton_action() method of the backing bean, so I suspect an attempt to set a property value not bound to a UI component may be the problem with your substitution.
I think when you use backing beans you have to bind the needed bean properties to components, using a "binding" parameter, and your suggestion omitted that parameter.
Anyway I believe the spirit of the exercise was to show how an action method bound to a UI button can update other components in the web site. I think we're using a backing bean rather than a managed bean because the data is completely transient and will not be saved.
One other minor issue with your suggestion is that the original code initialized the outputText component to "Hello!", and the suggested version omits the initialized string and immediately presents a null string.
Binding is something that tends to get overused. I think that pre-1.0 JSF it may have been more important than it is now. However there is still a use for binding, and your little exercise shows one of those uses, which is a case where you're using it to obtain a handle to the InputText control so that you can modify it.
Actually, this exercise is a little contrived, since the way I normally disable input on an inputTextControl is by using the "disabled" attribure and an EL expression, but academic exercises are often contrived. There's no special benefit to binding the output control here that I noticed, which is why I coded a straight property reference with no binding. But I missed the tree in the forest that said that the property in question was the control, and not the property. My apologies.
I think that your problem is that you don't have a ValueBinding for your controls. The valuebinding would attach the controls to a specific property of a specified bean.
In MVC terms the HtmlInput and HtmlOutput controls are Controllers. They need corresponding Models. When you invoke "setValue" and "getValue" on them and there's no value binding, there's no model to hold the data, and JSF tends to treat missing values as something to be ignored rather than throwing errors where it's sensible to to that.
You did supply a value on the OutputText, but it's a String, not a mutable value binding, so I'm not sure about that part, but I suspect if you logged what's coming from the InputText, you would find that the data wasn't being returned because there was no place to store it.