Search code examples
jspelstrong-typingcustom-tags

How can I pass an integer value as a parameter in my custom JSP tag?


I have a self made tag-library that I use in JSP. I have a problem with my contains -tag.

This is a generic contains-check, that accepts a list, and an object, and performs a simple check if the list contains the object. However, I've run into problems when the list contains Integer values.

This is how I call the tag:

<custom:contains  object="1" list="${sessionScope.USER.userProfiles}"/>

And here is the java class it invokes:

public class ContainsTag extends SimpleTagSupport{
    private List<Object> list;
    private Object object;

    public void setList(List<Object> list) {
        this.list = list;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    @Override
    public void doTag() throws JspException, IOException {      

        boolean result;
        try {
            if(list == null || object == null){
                result = false;
            }
            else{
                result = list.contains(object);
            }

            getJspContext().getOut().print(result);
        } catch (Exception e) {
            e.printStackTrace();
            // stop page from loading further by throwing SkipPageException
            throw new SkipPageException("Exception in checking if " + list
                    + " contains " + object);
        }
    }
}

Printline statements show that even though the object prints 1, and the list prints [1], the result is false. Since the tag works for other types of objects (Strings etc), this leads me to the conclusion that object is a String value, and is therefor not found in a list of integers. I cannot exactly cast the object to an integer either, as my tag wouldn't be generic anymore.

Is there a way to specify that a parameter is an integer value in EL? Do I need to make another tag called ContainsInteger? Or are there other solutions to this problem?

UPDATE:

setting the object value to "${1}" instead of "1", made no difference...


Solution

  • The object="1" won't work because it represents a String.

    String string1 = "1";
    Integer integer1 = new Integer(1);
    System.out.println(string1.equals(integer1)); // false
    

    The object="${1}" won't work because integer based numbers in EL default to Long. See section "1.7.1 Binary operators - A {+,-,*} B" in the "Expression Language Specification" (specified by JSR-341) for more details.

    Long long1 = new Long(1L);
    Integer integer1 = new Integer(1);
    System.out.println(long1.equals(integer1)); // false
    

    One way to solve your problem is to use a List<Long> instead of List<Integer>, or to let the custom tag compare the toString() result of both hands instead.

    String string1 = "1";
    Integer integer1 = new Integer(1);
    System.out.println(string1.toString().equals(integer1.toString())); // true
    
    Long long1 = new Long(1L);
    Integer integer1 = new Integer(1);
    System.out.println(long1.toString().equals(integer1.toString())); // true