How to convert an arbitrary object to String with EL + JSTL? (calling toString())
Asked Answered
S

6

12

Is there any way to call toString() on an object with the EL and JSTL? (I need the String representation of an enum as index in a map in a JSP EL expression.) I hoped something like ${''+object} would work like in java, but EL isn't that nice, and there does not seem to be any function that does it.

Clarification: I have a variable somemap that maps Strings to Strings, and I have a variable someenum that is an enumeration. I'd like to do something like ${somemap[someenum.toString()]}. (Of course .toString() does not work, but what does?)

Sarita answered 21/5, 2010 at 16:20 Comment(4)
I fixed "JSTL" in your question to "EL". The ${} things are not JSTL. It is Expression Language (EL). JSTL is the standard taglib, e.g. c:out, c:forEach, etc.Crural
It really is EL + JSTL - the solution does not work with EL alone but both.Rikkiriksdag
Your actual problem is with EL, not with JSTL. JSTL is just a dumb flow control taglib which knows absolutely nothing about expressions and backend data like enums.Crural
see https://mcmap.net/q/892102/-how-to-convert-an-arbitrary-object-to-string-with-el-jstl-calling-tostring, the ${'' + object} is not valid, but you can use ${''}${object}Morelock
L
29

You just do it like this:

${object}

And it'll toString it for you.


edit: Your nested expression can be resolved like this:

<c:set var="myValue">${someenum}</c:set>
${somemap[myValue]}

The first line stringifies (using toString()) the ${someenum} expression and stores it in the myValue variable. The second line uses myValue to index the map.

Licastro answered 21/5, 2010 at 16:26 Comment(3)
Right, but I can't use this inside in an EL expression. See my clarification; ${somemap[${someenum}]} is not allowed.Rikkiriksdag
<c:set var="myValue">${someenum}</c:set> works here because the value is within the Body of the c:set tag, so the value has to get toString()'d. Note that if you did <c:set var="myValue" value="${someenum}"/> then it will retain it's type (enum) and not get converted to a String.Carroll
@Hans-PeterStörr right, that is not valid syntax... you can't have ${} within another ${} expression, and you don't need to. It would just be ${somemap[someenum]}. However, since you want someenum to be converted to String, you can't do it this way in one-line, you have to convert it first. <c:set var="someEnumString">${somenum}</c:set> then ${somemap[someEnumString]}Carroll
T
6

Couple things you can do.

One, you can use c:set -

<c:set var="nowAString">${yourVar}</c:set>

Another thing you can do is create your own EL function, call it toString, and then call that in JSTL. EL functions are basically static methods hooked up with a taglib file. Straightforward to do.

Edit:

Really? Did you actually, you know, try it?

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<%@taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <%
        pageContext.setAttribute("testDate", new java.util.Date());
        %>

        <c:set var="myVar">${testDate}</c:set>
        testDate = ${testDate}<br/>
        myVar = ${myVar}<br/>
        testDate Class = ${testDate.class}<br/>
        myVar Class = ${myVar.class}<br/>
    </body>
</html>

And JSP 2.0 tagfile and JSTL functions are trivial.

Transported answered 21/5, 2010 at 16:42 Comment(1)
Note that is important to use the body, not the value attribute if you are trying to use c:set to do toString(). If x is an Integer... <c:set var="foo" value="${x}"/> foo will still be an Integer <c:set var="foo">${x}</c:set> foo will be a StringCarroll
G
3

I think in new versions of JSP api you can call methods, even with parameters!

I just tried ${statusColorMap[jobExecution.exitStatus.toString()]} and it works fine!

Greenburg answered 30/11, 2012 at 14:27 Comment(1)
I'm using EL to write JXLS Template. And toString method save my day. Thanks!Anatolio
C
1

The answer of Will Hartung should work. Here's a copy'n'paste'n'runnable SSCCE:

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!doctype html>

<%!
    enum MyEnum {
        FOO, BAR
    }
%>
<%
    request.setAttribute("myEnum", MyEnum.FOO);
    java.util.Map<String, String> map = new java.util.HashMap<String, String>();
    map.put("FOO", "value of key FOO");
    map.put("BAR", "value of key BAR");
    request.setAttribute("map", map);
%>

<html lang="en">
    <head>
        <title>Test</title>
    </head>
    <body>
        <p>Map: ${map}
        <p>Enum: ${myEnum}
        <c:set var="myEnumAsString">${myEnum}</c:set>
        <p>Map value: ${map[myEnumAsString]}        
    </body>
</html>

This yields:

Map: {BAR=value of key BAR, FOO=value of key FOO}

Enum: FOO

Map value: value of key FOO

(scriptlets are just for quick prototyping, don't use them in real!)

Crural answered 21/5, 2010 at 19:16 Comment(0)
L
0
//In java

public class Foo {
    // Define properties and get/set methods
    private int prop1;
    private String prop2;



    public String toString() {
        String jsonString = ...; /// Convert this object to JSON string
        return jsonString;
    }
}

As skaffman said, EL syntax ${obj} will call toString().

So, if a object foo in JSTL is an instance of Foo. Then,

// test.jsp

<script>
    var a = ${foo};  // ${foo} will be {"prop1": ooo, "prop2": "xxx"}
    console.log(a.prop1);
    console.log(a.prop2);
</script>

Example

If toString() will output JSON format string, for example, Foo's toString() outputs JSON format string. then:

// .java codes
Foo a = ...// a Foo object. => { 'prop1': ooo }
List<Foo> b = ... //< Array. => [ {'prop1': ooo}, {prop1: xxx} ]

// Pass object to JSTL by HttpServletRequest or ..
request.setAttribute('a', a);
request.setAttribute('b', b);

// .jsp codes
<span>${a.prop1}</span>

<script>
    var aa = ${a}; // ${a} => { 'prop1': ooo }
    var bb = ${b}; // ${b} => [ {'prop1': ooo}, {prop1: xxx} ]

    console.log(aa.prop1);
    console.log(bb[0].prop1);
</script>
Lean answered 15/8, 2017 at 3:33 Comment(0)
M
-1

ugly but simple enough

<someTag someValue="${yourObject}${''}" ... />

for example, someValue only accept strings (but declare as java.lang.Object), this way enforce it with string concatenation

Morelock answered 13/3, 2019 at 7:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.