2

I'm trying to figure out if there's any functional difference between these two uses of the JSTL <c:set> tag. Let's assume I have imported some string constants into my JSP page via something like:

<%@ page import="some.package.of.AppConstants"%>

So, given the above import directive, what's the difference between these two examples:

  1. Specifying the value in value attribute:

    <c:set var="SOME_VAR" value="${AppConstants.SOME_CONSTANT}" />
    
  2. Specifying the value in tag body:

    <c:set var="SOME_VAR">
        <%=AppConstants.SOME_CONSTANT%>
    </c:set>
    

Is there any difference in what the value of ${SOME_VAR} will be in the second example versus the first example? Would the presence of any special characters in AppConstants.SOME_CONSTANT affect the value of ${SOME_VAR} in either of these cases?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
minorgod
  • 652
  • 6
  • 7

2 Answers2

4

Difference between jstl c:set value in attribute and body of tag

There is a technical difference.

The value keeps the original value type. E.g., if you supplied Integer or whatever, it will stay Integer. The body, however, basically does a toString() on the value and thus essentially converts any type to String. This can be beneficial in some cases, e.g.:


Coming back to the concrete functional requirement, the first example will only work if you're targeting a Servlet 3.1 / EL 3.0 container (Tomcat 8, etc) with a webapp whose web.xml matches Servlet 3.1.

<c:set var="SOME_VAR" value="${AppConstants.SOME_CONSTANT}" />

Namely, this is only supported since EL 3.0. This is definitely the preferred approach over the Scriptlet way. You should try to avoid Scriptlets at all cost. You only need to keep in mind that the code is not backwards compatible with older versioned target runtimes.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

According to O'Reillys HeadsFirstServlets pg 457, why would you use the body version of c:set instead of the no-body version. It looks like they do the same thing.

Answer:

That’s because they DO... do the same thing. The body version is just for convenience when you want more room for the value. It might be a long and complex expression, for example, and putting it in the body makes it easier to read.

Update

After some additional research it turns out the above reasoning pertains only to EL v2.2 and lower. See the answer by BalusC for 3.0 behavior.

Mike
  • 2,399
  • 1
  • 20
  • 26
  • Thanks for your comment. It turns out my prob was not related to using an attribute versus body to assign the value. I finally figured out that the key difference was in the way I was assigning the values, using an expression in the first example and a scriptlet in the 2nd example. It turns out that in Expression Language 2.x, imported class/interface are not in scope and therefore can't be referenced using EL (eg: ${AppConstants.SOME_CONSTANT}). They must instead be referenced via a scriptlet. I'm voting up your reply anyway because you were the only person who tried to answer constructively – minorgod Dec 23 '15 at 19:16