Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<c:if test='${not empty "${records}"}'> never evaluates false

Tags:

java

jsp

jstl

I am having a problem with JSTL and empty operator. I already made few simple pages and everything worked fine, but now I have:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <html>
    <body>

     <form action="/Projekt/myaccount" method="post">
    <table border="1">
        <tr>
                 <td>Artist</td>
                 <td>Record Name</td>
                 <td>Delete</td>
         </tr>
        <c:forEach var="item" items="${records}">
         <tr>
                 <td>${item.artist}</td>
                 <td>${item.recordName}</td>
                 <td>
                    <input type="checkbox" name='${item.recordName}|${item.recordName}'/>
                 </td>
         </tr>
        </c:forEach>
    </table>
    <hr/>
        <input type="submit" name="back" value="back"/>
        <c:if test='${not empty "${records}"}'>
               <input type="submit" name="delete" value="delete selected"/>
        </c:if>
     </form>
    </body>
    </html>

now no matter if I set the records attribute or not, the delete button shows up:

<c:if test='${not empty "${records}"}'>
           <input type="submit" name="delete" value="delete selected"/>
    </c:if>

in normal situation to records attribute I pass ArrayList and then use foreach, but sometimes ArrayList is empty, so in those situations I don't want delete button to show up, I fought that easiest way to achieve this would be to use this empty operator. Where am I making a mistake?

I even tried to manually set this attribute to null:

if (ar.size() != 0)
    request.setAttribute("records", ar);
else
    request.setAttribute("records",null);

EDIT: @Qwe: yes you are right, it worked for me before because I tested if attribute was empty in my way, it was always true, because I used wrong construct, but it worked because I just wanted to show one string, if there was no String nothing showed up so I was thinking that everything worked fine.

like image 283
Andna Avatar asked Feb 11 '12 20:02

Andna


1 Answers

<c:if test='${not empty "${records}"}'> as well as <c:if test="${!empty '${showWarning}'}"> (from your comment) will always resolve to true because you're are actually testing if a String ${records} is empty or not, and obviously it is not.

Just to be sure - by String ${records} I mean a String value, just as if you were assigning it in Java like String foo = "${records}";.

The next line of code will test if records variable (that is looked up from page, request, session or application scope) is empty or not:

<c:if test="${not empty records}">

The line of code is 100% guaranteed to work :)

Also, request.setAttribute("records",null) is a bad way to remove attributes because empty tests not just request scope, but page, session etc. Use <c:remove var='records'/> instead.

like image 99
Oleg Mikheev Avatar answered Sep 28 '22 00:09

Oleg Mikheev