jsp set variable variable name

TheOneWhoPrograms picture TheOneWhoPrograms · Jun 6, 2014 · Viewed 15.3k times · Source

I have been looking how to do this properly but cannot find a definitive guide on how to do with.

I know that you cannot use an expression within the tag, but I am unsure how else I am meant to approach it.

I've seen a multitude of answers for this without much explanation or help.

Essentially I want something like the following to work, but obviously doesn't.

<c:forEach items="${dataposition.rows}" var="lineposition" begin="0" varStatus="status">
    <c:set var="name_${status.count}" value="${lineposition.value}" scope="session"/>
</c:forEach>

The exact error message is

"According to TLD or attribute durective in tag file, attribute var does not accept any expressions"

What is the proper way to accomplish this?

(I changed the variable names from my actual code, but hopefully you still get the idea)

If I need to create java objects or something I am fine with that, but I would need to know how to include them in my project and how to use them within the code. Something like a list sounds about right.

I have created an object to hold my values for me.

<jsp:useBean id="myid" class="myclass" scope="session"/>

and I want to use it, but am unsure how:

<c:forEach items="${dataposition.rows}" var="lineposition" begin="0" varStatus="status">
    <%
        myid.add_position(lineposition.var1, lineposition.var2, lineposition.var3, lineposition.var4, lineposition.var5);
    %>
</c:forEach>

Answer

Erik Gillespie picture Erik Gillespie · Jun 6, 2014

Using an MVC framework to separate the code to setup your data from how you want to present it would be the ideal way to go. If you have a controller of any kind that executes on the server before your JSP is rendered then I would recommend putting your logic there. Besides the controller being the more appropriate place to prepare this sort of data, the syntax will almost definitely look more clean than anything you could put on the JSP to make this work.

If you don't have a controller and you're only using JSPs then I guess I would recommend writing a tag to replace <c:set>. This is not the cleanest approach but if JSPs are what you're stuck with then it seems like a decent compromise to me (I think it's better than scriptlets and hacking the JSTL core TLD to allow expressions in the "var" attribute anyway). It would do all of the same things as <c:set> except the TLD could be written to allow expressions in the "var" attribute.

MyTag.java

package example;

import org.apache.taglibs.standard.tag.rt.core.SetTag;

public class MySetTag extends SetTag { }

WEB-INF/my.tld

<taglib>
    <tag>
        <name>set</name>
        <tag-class>example.MySetTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>var</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        ...
    </tag>
</taglib>

rownamer.jsp

<%@ taglib prefix="my" uri="WEB-INF/my.tld"%>
<c:forEach items="${dataposition.rows}" var="lineposition" begin="0" varStatus="status">
    <my:set var="name_${status.count}" value="${lineposition.value}" scope="session"/>
</c:forEach>