12

If an object property is declared as of type Boolean (not primitive boolean) then there seem to be a problem in EL recognizing it!

Say you have the following object

class Case{
     private Boolean  valid;

     public Boolean isValid(){
         return this.valid;
     }

     public void setValid(Boolean val){
         this.valid = val;
     }
}

Say we put an object of type Case in the request under the name "case", then I try this in the JSP:

<td>Object is ${case.valid ? "Valid":"Invalid"} </td>

This gives me error "valid" is not a property of object Case! If I change valid from Boolean to primitive boolean it works!

Is this a known problem with Boolean types in EL that they are not recognized as boolean but as Java "normal" objects? What is the proper way to handle this?

Thanks

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
DhafirNz
  • 627
  • 3
  • 9
  • 20
  • I'm a noob JSP user, but wouldn't the `private` in your `valid` object variable declaration mean you can't access it directly? – Jared Farrish Apr 18 '11 at 01:12
  • Yes, this is true in Java world, but with EL you can access object properties using JavaBean style (object.propertyName) providing that you provided a getter (isValid in this case). So when you say case.valid you are actually calling case.isValid(). You can see that if I change Boolean to boolean it works fine. – DhafirNz Apr 18 '11 at 01:19
  • So if you call the method `isValid()`, it doesn't work as well? – Jared Farrish Apr 18 '11 at 01:20
  • you cannot call isValid() in EL, as I said, you use JavaBean accessing style object.propertyname. – DhafirNz Apr 18 '11 at 01:21
  • So I guess my next question is, if you change that declaration to public, it doesn't work? (just checking) – Jared Farrish Apr 18 '11 at 01:32
  • No, you are not accessing the property directly, you are accessing it via case.isValid(0 but the way to do it in EL is by saying case.valid. – DhafirNz Apr 18 '11 at 01:54
  • I'll take your word for it. I don't know nearly enough to argue it in any case, thanks for taking the time to explain. – Jared Farrish Apr 18 '11 at 01:57
  • Not entirely certain here but I'm guessing if you add a `getValid()` method that delegates to `isValid()`, it should work. – no.good.at.coding Apr 18 '11 at 03:18

3 Answers3

20

All the examples I've ever seen talk about boolean properties that allow getters of the form isProperty() in addition to getProperty() and never Booleans.

I can't find any 'official' reference to this behaviour but this blog post seems to describe what I suspected when I commented initially - a Boolean is an object while a boolean is a primitive and while Java has auto-boxing, EL will ignore the isProperty() getter that returns a Boolean and will instead, look for a getProperty() method.

So I suspect that, in your example, if you changed the return type of isValid() to boolean instead of Boolean (but leave the type of the field as Boolean), your EL expression will work as you expect.

no.good.at.coding
  • 20,221
  • 2
  • 60
  • 51
  • 4
    Blog post does not exists. – Grim May 24 '14 at 08:03
  • Excellent thought, about Boolean/boolean and is/get. It really helped me. +1 here and +1 on another answer of yours. But the blog mentioned does not exist anymore and who knows where can we get full info, about variants with setting b/Boolean for fields and functions and args, and the behaviour can be different for different servers if it is not described in the docs... BTW, according to my experiments, boolean for is... did not work, only Boolean for get... (JBoss) – Gangnus Nov 22 '20 at 16:51
5

EL treats Boolean as an object (which is totally correct) so it looks for getValid() method. This is consistent with JavaBeans specification.

Try changing your property from Boolean reference type to boolean primitive type. If this is not possible and you're using new EL (i.e. 2.2 - I'm not sure about 2.1) you can invoke a method, so ${case.isValid()} would be an example of a correct usage of this new EL feature.

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
Pedro
  • 51
  • 1
0

Some combinations of is/get-getters, Boolean/boolean fields and Boolean/boolean getters are allowed or forbidden by JSP. It is as follows:

Forbidden combinations:

Boolean method, getting by is

Allowed combinations:

Boolean method, getting by get
boolean method, getting by is
boolean method, getting by get

Boolean/boolean type of field is irrelevant.

In IntelliJ it is enough to generate getters automatically.


Checked by launching all combinations.

    <c:if test="${actionBean.code_FMI}">
        <div>Boolean field, Boolean method, getting by is</div>
    </c:if>
    <c:if test="${actionBean.code_FMG}">
        <div>Boolean field, Boolean method, getting by get</div>
    </c:if>
    <c:if test="${actionBean.code_FmI}">
        <div>Boolean field, boolean method, getting by is</div>
    </c:if>
    <c:if test="${actionBean.code_FmG}">
        <div>Boolean field, boolean method, getting by get</div>
    </c:if>
    <c:if test="${actionBean.code_fMI}">
        <div>boolean field, Boolean method, getting by is</div>
    </c:if>
    <c:if test="${actionBean.code_fMG}">
        <div>boolean field, Boolean method, getting by get</div>
    </c:if>
    <c:if test="${actionBean.code_fmI}">
        <div>boolean field, boolean method, getting by is</div>
    </c:if>
    <c:if test="${actionBean.code_fmG}">
        <div>boolean field, boolean method, getting by get</div>
    </c:if>

Java bean:

private Boolean code_FMI = true, code_FmI = true, code_FMG = true, code_FmG = true;
private boolean code_fMI = true, code_fmI = true, code_fMG = true, code_fmG = true;

public Boolean isCode_FMI() {
    return code_FMI;
}

public boolean isCode_FmI() {
    return code_FmI;
}

public Boolean getCode_FMG() {
    return code_FMG;
}

public boolean getCode_FmG() {
    return code_FmG;
}

public Boolean isCode_fMI() {
    return code_fMI;
}

public boolean isCode_fmI() {
    return code_fmI;
}

public Boolean getCode_fMG() {
    return code_fMG;
}

public boolean getCode_fmG() {
    return code_fmG;
}
Gangnus
  • 24,044
  • 16
  • 90
  • 149