45

I am creating a drop down list of all languages. The default language selection for the list will be determined by information added by the user:

<select>
    <c:forEach items="${languages}" var="lang">
        <c:choose>
            <c:when test="${lang}.equals(${pageLang})">
                <option value="${lang}" selected>${lang}</option>
            </c:when>
            <c:otherwise>
                <option value="${lang}">${lang}</option>
            </c:otherwise>
        </c:choose>
    </c:forEach>
</select>

.equals doesn't appear to exist in EL. Having had a look here it's suggested I write my own function and then import and use that. As this is a one off tiny thing just for this page I don't want to have to start creating libraries etc just for this. Nor do I want to start creating specialist objects for the servlet to return with this extra info in them.

Only thing I can think to do is to return the actual html for the whole option line from the servlet rather than just the language string, but that strikes me as ugly so I'm hoping there's a more elegant solution.

What is the best plan for a quick fix to comparing two strings in EL?

The J2EE 1.4 Tutorial

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Caroline
  • 1,582
  • 3
  • 16
  • 30

2 Answers2

106

In Expression Language you can just use the == or eq operator to compare object values. Behind the scenes they will actually use the Object#equals(). This way is done so, because until with the current EL 2.1 version you cannot invoke methods with other signatures than standard getter (and setter) methods (in the upcoming EL 2.2 it would be possible).

And you need to make sure that the entire expression is placed inside the same ${...} scope. Anything outside that is not interpreted as part of an EL expression.

So the particular line

<c:when test="${lang}.equals(${pageLang})">

should be written as (note that the whole expression is inside the { and })

<c:when test="${lang == pageLang}">

or, equivalently

<c:when test="${lang eq pageLang}">

Both are behind the scenes roughly interpreted as

jspContext.findAttribute("lang").equals(jspContext.findAttribute("pageLang"))

If you want to compare constant String values, then you need to quote it

<c:when test="${lang == 'en'}">

or, equivalently

<c:when test="${lang eq 'en'}">

which is behind the scenes roughly interpreted as

jspContext.findAttribute("lang").equals("en")
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    I'm assuming I can use `test="${lang eq 'en'}" then too? I see `eq` up there, but it wasn't with string constants? Just making sure, I don't frequent myself with JSTL/expression language often – mswieboda Sep 25 '13 at 18:38
  • 1
    @Sucker: `eq` is an alias for `==`. They do both exactly the same. See also [operators in EL](http://docs.oracle.com/javaee/6/tutorial/doc/bnaik.html). – BalusC Sep 25 '13 at 18:43
  • It works EXCEPT in 1 letter String comparison case. Then you should use (swap simple for double quotes) http://struts.apache.org/release/2.0.x/docs/why-wont-the-if-tag-evaluate-a-one-char-string.html – exoddus Sep 17 '14 at 08:37
  • @exoddus: please don't confuse OGNL with EL. – BalusC Sep 17 '14 at 09:45
  • Can you also give an example as to how to add multiple test conditions(i.e. more than one) using `&&` or `||` in the test clause ? – KNU Oct 20 '14 at 14:07
  • @BalusC `` is it correct way? – KNU Oct 20 '14 at 15:43
3

Not sure if I get you right, but the simplest way would be something like:

<c:if test="${languageBean.locale == 'en'">
  <f:selectItems value="#{customerBean.selectableCommands_limited_en}" />
</c:if>

Just a quick copy and paste from an app of mine...

HTH

KB22
  • 6,899
  • 9
  • 43
  • 52
  • Hey, I think you're comparing a string to a 'constant' string here? languageBean.locale == 'en'? Whereas I'm comparing two variables, hence '==' won't work as that'll compare pointers. Thanks, CJ – Caroline Dec 14 '09 at 13:19
  • but actually, partially correct, as BalusC explains that the '==' is the correct operator after all and I can use that! – Caroline Dec 14 '09 at 13:42
  • 3
    "Quick copy and paste" code snippets without actually **understanding** what they do is very harmful and doesn't put yourself in a big respect. I recommend not to do so. The same applies to mixing JSF with JSTL the way as you represented in the code snippet, but that's another story. – BalusC Dec 14 '09 at 13:53
  • @BalusC: is there a problem using JSF and JSTL together? Isn't JSF a higher-level framework than JSTL? – Mr. Shiny and New 安宇 Dec 14 '09 at 14:11