[jboss-user] [JBoss Seam] - JSF rendering of invalid values

christian.bauer@jboss.com do-not-reply at jboss.com
Thu Apr 5 01:59:45 EDT 2007


To debug another problem I need to know how JSF gets component values during RENDER RESPONSE after validation fails. I basically need someone who knows JSF internals :)

Form:


  | <h:form id="commentForm">
  | 
  |             <s:validateAll>
  | 
  |                     <s:decorate id="foobarDecorate">
  |                         <div class="entry">
  |                             <div class="label">Entity test string:</div>
  |                             <div class="input">
  |                                 <h:inputText tabindex="1" size="40" maxlength="100" required="true"
  |                                              id="foobar" value="#{testBean.testEntity.testString}">
  |                                 </h:inputText>
  |                             </div>
  |                         </div>
  |                     </s:decorate>
  | 
  |                 <s:decorate id="bazDecorate">
  |                     <div class="entry">
  |                         <div class="label">Test string:</div>
  |                         <div class="input">
  |                             <h:inputText tabindex="1" size="40" maxlength="100" required="true"
  |                                          id="baz" value="#{testBean.testString}">
  |                             </h:inputText>
  |                         </div>
  |                     </div>
  |                 </s:decorate>
  | 
  |             </s:validateAll>
  | 
  |             <div class="entry">
  |                 <div class="label"> </div>
  |                 <div class="input">
  | 
  |                     <h:commandLink action="#{testBean.doSomething}"
  |                                    styleClass="button"><span class="buttonLabel">Do Something</span></h:commandLink>
  | 
  |                 </div>
  |             </div>
  | 
  | </h:form>
  | 

The backing bean:


  | @Name("testBean")
  | @Scope(ScopeType.PAGE)
  | public class TestBean implements Serializable {
  | 
  |     @In(required = false)
  |     private FacesMessages facesMessages;
  | 
  |     private String testString;
  | 
  |     public String getTestString() {
  |         System.out.println("#### GETTING: " + testString);
  |         return testString;
  |     }
  | 
  |     public void setTestString(String testString) {
  |         System.out.println("#### SETTING: " + testString);
  |         this.testString = testString;
  |     }
  | 
  |     private TestEntity testEntity;
  | 
  |     public TestEntity getTestEntity() {
  |         System.out.println("######## GETTING ENTITY INSTANCE");
  |         return testEntity;
  |     }
  | 
  |     @Create
  |     public void create() {
  |         System.out.println("###################### NEW TEST ENTITY");
  |         testEntity = new TestEntity();        
  |     }
  | 
  |     public void doSomething() {
  |         System.out.println("################ DO SOMETHING ############################");
  | 
  |         facesMessages.addFromResourceBundleOrDefault(
  |             FacesMessage.SEVERITY_ERROR,
  |             "didSomething", "Hello! This is a message! Current test string is: " + testString + " and in entity it's: " + testEntity.testString );
  | 
  |         facesMessages.addToControl(
  |             "foobar",
  |             FacesMessage.SEVERITY_ERROR,
  |             "Message for component!");
  | 
  |     }
  | 
  |     public static class TestEntity implements Serializable {
  | 
  |         @Length(min = 3, max = 255)
  |         private String testString;
  | 
  |         public String getTestString() {
  |             System.out.println("#### GETTING INSIDE ENTITY: " + testString);
  |             return testString;
  |         }
  | 
  |         public void setTestString(String testString) {
  |             System.out.println("#### SETTING INSIDE ENTITY: " + testString);
  |             this.testString = testString;
  |         }
  |     }
  | 
  | }
  | 

When I enter "a" and "b" into the two form fields, validation for the first field should fail (@Length on the entity class). It does so, and it shows me the form again with "a" and "b" in the fields and the decorated validation error message.

How do the values "a" and "b" get into the form components during RENDER RESPONSE? This is what I see in the logs:


  | 07:47:49,321 DEBUG [SeamPhaseListener] before phase: APPLY_REQUEST_VALUES(2)
  | ... Nothing interesting ...
  | 07:47:49,325 DEBUG [SeamPhaseListener] after phase: APPLY_REQUEST_VALUES(2)
  | 07:47:49,325 DEBUG [SeamPhaseListener] before phase: PROCESS_VALIDATIONS(3)
  | ... Nothing interesting ...
  | 07:47:49,327 DEBUG [RootInterceptor] intercepted: testBean.getTestEntity
  | 07:47:49,328 INFO  [STDOUT] ######## GETTING ENTITY INSTANCE
  | 07:47:49,328 DEBUG [RootInterceptor] intercepted: testBean.getTestEntity
  | 07:47:49,329 INFO  [STDOUT] ######## GETTING ENTITY INSTANCE
  | 07:47:49,333 DEBUG [RootInterceptor] intercepted: testBean.getTestString
  | 07:47:49,333 INFO  [STDOUT] #### GETTING: null
  | 07:47:49,333 DEBUG [SeamPhaseListener] after phase: PROCESS_VALIDATIONS(3)
  | 07:47:49,334 DEBUG [AbstractSeamPhaseListener] committing transaction after phase: PROCESS_VALIDATIONS(3)
  | 07:47:49,334 DEBUG [SeamPhaseListener] before phase: RENDER_RESPONSE(6)
  | ... Nothing interesting ...
  | 07:47:49,664 DEBUG [RootInterceptor] intercepted: testBean.getTestEntity
  | 07:47:49,665 INFO  [STDOUT] ######## GETTING ENTITY INSTANCE
  | 07:47:49,665 INFO  [STDOUT] #### GETTING INSIDE ENTITY: null
  | 07:47:49,690 DEBUG [SeamPhaseListener] after phase: RENDER_RESPONSE(6)
  | 

So during PROCESS VALIDATIONS, my backing bean getters are being called. Why that is the case I don't know, maybe this is triggered by <s:validateAll> (haven't been able to figure out how this is implemented) or simply the JSF implementation randomly calling my model. 

Then validation obviously fails. During RENDER RESPONSE, the two input components are rendered again. They magically get the values "a" and "b" that I entered into the form. From where and how? Obviously not from my model or backing bean, because only one of them calls it's bound getter, and even that returns null.



View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4034864#4034864

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4034864




More information about the jboss-user mailing list