Cannot read Boolean property in JSP EL [duplicate]
Asked Answered
B

3

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

Bowlin answered 18/4, 2011 at 1:5 Comment(8)
I'm a noob JSP user, but wouldn't the private in your valid object variable declaration mean you can't access it directly?Emblazonment
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.Bowlin
So if you call the method isValid(), it doesn't work as well?Emblazonment
you cannot call isValid() in EL, as I said, you use JavaBean accessing style object.propertyname.Bowlin
So I guess my next question is, if you change that declaration to public, it doesn't work? (just checking)Emblazonment
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.Bowlin
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.Emblazonment
Not entirely certain here but I'm guessing if you add a getValid() method that delegates to isValid(), it should work.Chare
C
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.

Chare answered 18/4, 2011 at 3:30 Comment(2)
Blog post does not exists.Pacifica
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)Retrograde
R
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.

Redingote answered 20/4, 2011 at 11:17 Comment(0)
R
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;
}
Retrograde answered 23/11, 2020 at 13:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.