Search code examples
jspjsp-tags

jsp:setproperty property=“*” not set all properties


i have jsp page which contains

<jsp:useBean id="RcvMsgTransferTanseekBean" class= "com.test.RcvMsgTransferTanseekBean" />  
<jsp:setProperty name="RcvMsgTransferTanseekBean" property="*" />

and bean which contain

private String nId = "";
public void setNId (String value){
    this.nId = value;  
}

public String getNId(){
    return this.nId;
}

i send request to that jsp page

test.jsp?letId=479438&dstId=522375&nId=138393&subject=66666666666&letForInfo=1&shNotMan=true

my problem is that the nId parameter only is still empty.

when i added new line in the jsp

<jsp:setProperty name="RcvMsgTransferTanseekBean" property="nId" />

it works fine, why the 'property="*"' didn't work as the supposed to be ?


Solution

  • The issue is in the name of the property.
    The Capitalization and Decapitalization of the CamelCase don't work as you expect for single leading letter. For Setting the value of the property the setter method are used.
    And the setter for nId is setNId.

    The Java Bean Spacification say:

    8.8 Capitalization of inferred names.

    When we use design patterns to infer a property or event name, we need to decide what rules to follow for capitalizing the inferred name. If we extract the name from the middle of a normal mixedCase style Java name then the name will, by default, begin with a capital letter. Java programmers are accustomed to having normal identifiers start with lower case letters. Vigorous reviewer input has convinced us that we should follow this same conventional rule for property and event names.

    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. So for example,

    “FooBah” becomes “fooBah” “Z” becomes “z” “URL” becomes “URL”

    We provide a method Introspector.decapitalize which implements this conversion rule.

    In the Documentation for Introspector:

    public static String decapitalize(String name)

    Utility method to take a string and convert it to normal Java variable name capitalization. This normally means converting the first character from upper case to lower case, but in the (unusual) special case when there is more than one character and both the first and second characters are upper case, we leave it alone.

    Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays as "URL".

    So in order to find match between parameter and setter:

    • The setter get decapitalized. So from setNId, we get NId.
    • If you have submitted a parameter NId, the value goes in the javaBean,
    • But if you have nId, there is no matching setter found.

    The Solution: Avoid such cases:

    Use more than one small letter at the begin of property names.

    In this particular case, instead of nId you can use numId.

    OR Change the setter/getter names to setnId() and getnId()

    Unexpected behavior by usage of Bean with such property and getter/setter names

    • <jsp:setProperty name="RcvMsgTransferTanseekBean" property="*" />
      just skips the property nId. No Error. No Exception.
    • <jsp:setProperty name="RcvMsgTransferTanseekBean" property="nId"/>
      throws org.apache.jasper.JasperException: PWC6054: Cannot find any information on property 'nId' in a bean of type 'com.test.RcvMsgTransferTanseekBean'
    • ${RcvMsgTransferTanseekBean.nId}
      throws org.apache.jasper.JasperException: javax.el.PropertyNotFoundException: The class 'com.test.RcvMsgTransferTanseekBean' does not have the property 'nId'.