Cant access some (Capitalized) fields in JSF controller?
Asked Answered
X

3

6

I Cant access some (Capitalized) fields in controllers
For Example

My controller (*.java)

package com.co.controller;

public class MyController {
    // fields
    private String FIELD;
    private String F1;

    // .... Controller code

    // Setters and Getters
    public String getFIELD() {
        return FIELD;
    }
    public void setFIELD(String fIELD) {
        FIELD = fIELD;
    }
    public String getF1() {
        return F1;
    }
    public void setF1(String f1) {
        F1 = f1;
    }
}

My Screen (*.xhtml)
When i try to use

<h:panelGrid>
    <h:outputText value="#{myController.FIELD}" />
    <h:outputText value="#{myController.F1}" />
</h:panelGrid>

The result is
F1 field: is NOT Accessible
HOWEVER
FIELD field : is Accessible

The Error appeared

Property 'F1' not found on type com.co.controller.MyController 

Also when i try to use

<h:panelGrid>
    <h:outputText value="#{myController.fIELD}" />
    <h:outputText value="#{myController.f1}" />
</h:panelGrid>

The result is
F1 field: is Accessible
HOWEVER
FIELD field : is NOT Accessible

Why that?

Xenophanes answered 24/2, 2014 at 11:23 Comment(3)
good question! however, there are naming conventions. please follow those.Englebert
@PhilippSander Agreed with you .. but i ask about why this behavior occurredXenophanes
i understand that and find it interessting too. it just wanted to point that out.Englebert
E
6

The BeanELResolver that translates your EL-Expressions to property access adheres to the JavaBean specification. It states (in Section 8.8):

Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone.

The resolver works by reflection on your actual class. It produces a list of FeatureDesriptor instances and matches those to your expression. So what the resolver sees from your bean is:

  1. Property FIELD, both read- and writable
  2. Transient property f1, read- and writable
  3. Unexposed property F1

Since you're trying to access F1, which has no getters and setters according to the JavaBeans specification, the resolver throws a PropertyNotFoundException.

To fix this, adhere to the normal camelCase convention and/or use longer names.

See also: Where is the JavaBean property naming convention defined?

Extinguisher answered 24/2, 2014 at 11:56 Comment(2)
@YajliMaclo nice find. Didn't know there even was a javabeans tag.Extinguisher
there is a not recommend workaround : if you have a field in the java bean named : Company and you want to access it in the jsf page you can access it as company with small letter (jsf here will call the getter which has the correct syntax getCapital)Gav
T
2

Its because that the ManagedBean has a naming pattern the get/set followed by an CamelCase letters of the word. JSF uses the setters as a way to access it in the xhtml, and not the field itself. If you have noticed, even if the field name or variable name is different, you can access it through the setters/getters.

private String FE123;

public String getFE12345() {
    return FE123;
}

public void setFE12345(String fE123) {
    this.FE123 = fE123;
}

you can access it like

   <h:outputText value="#{managedBean.FE12345}" />

not

   <h:outputText value="#{managedBean.FE123}" />

In the case of field:

getField();
getFIELD();

JSF knows that the second character in the FIELD is an uppercase I. so it identifies it as an all Uppercase field.So you can use it as managedBean.FIELD. If you use the getField, you can get it as

<h:outputText value="#{managedBean.field}" />

But in the case of

getF1();

JSF sees that the second character is 1 that does not have an uppercase or lowercase. so basing that the JSF uses setters/getters to get the field. because of the ManagedBean specification after the get/set is an uppercase, thats why it you can use it in managed bean as:

 <h:outputText value="#{managedBean.f1}" />

sorry for the bad explanation, hope you understand

Totalitarian answered 24/2, 2014 at 11:54 Comment(0)
C
1

The attribute name does not interfere.

But your method declaration should follow the convention.

private String FIELD;

 public String getField() {
        return FIELD;
    }

xhtml

<h:outputText value="#{seasonSearchController.field}" />

The javadoc documentation does not explicitly tells us that naming convention is mandatory. Rather it tell us it's optional and recommended

For simple properties the accessor type signatures are:

void setFoo(PropertyType value); // simple setter PropertyType getFoo(); //

simple getter GetFoo and setFoo are simply example names. Accessor methods can have arbitrary names. However for standard naming conventions for accessor methods see the design patterns described in Section 8.3.

8.3.1 Simple properties

By default, we use design patterns to locate properties by looking for methods of the form:

public <PropertyType> get<PropertyName>(); 
public void set<PropertyName>(<PropertyType> a);

If we discover a matching pair of “get” and “set” methods that take and return the same type, then we regard these methods as defining a read-write property whose name will be “”. We will use the “get” method to get the property value and the “set” method to set the property value. The pair of methods may be located either in the same class or one may be in a base class and the other may be in a derived class.

If we find only one of these methods, then we regard it as defining either a read-only or a writeonly property called “” By default we assume that properties are neither bound nor constrained (see Section 7). So a simple read-write property “foo” might be represented by a pair of methods:

public Wombat getFoo(); 
public void setFoo(Wombat w);
Carbonaceous answered 24/2, 2014 at 11:43 Comment(4)
That's a workaround, but what's causing F1 not to be considered a property?Extinguisher
Jup, that statement about getters having abritrary names got me confused at first, too. But the EL-resolver is using introspection and this is governed by section 8 of the JavaBean spec which uses these patterns as a way to auto-discover the available property names.Extinguisher
Yes, I got confused too. That's why I added the 8.3.1 section. I think this way: it's not mandatory, but if something that was supposed to work is not working, I try to stick to the naming convention. :-)Carbonaceous
My point was: in the context of EL, following the "recommendations" is required. Not by the JavaBeans spec but by the way resolving EL expressions works.Extinguisher

© 2022 - 2024 — McMap. All rights reserved.