Вы не можете смешивать JSTL с таким javascript. JSTL отображается на стороне сервера, что означает, что сервер запустит этот код до того, как запустит JavaScript. Javascript отображается на стороне клиента.
Вы можете проверить это самостоятельно, выполнив следующее:
<button onclick="doTest();">Test</button>
<script>
function doTest() {
//this should only run when we click on the button right?
<c:set var="testMe" value="Wrong." scope="session" />
}
</script>
<p>There should be no text below until we click the button right?</p>
<h1><c:out value="${testMe}"/></h1>
Так что вам нужно пересмотреть свой код, помня об этом, что любой jstl, который есть в вашем javascript, будет запускаться первым. Вот почему он покажет только одно информационное окно.
Чтобы это работало, нужно передать ваш $ {itemList} на скрытый ввод.
<input type="hidden" value="${itemList}" id="getItemList">
тогда в javascript вы можете получить к нему доступ и создать цикл с использованием javascript, а не jstl. Хотя сначала вам нужно будет преобразовать объект в строку или строку json, чтобы использовать ее в javascript.
Вы можете сделать это с помощью чего-то подобного в вашей Java:
String someObjectAsJson = new Gson().toJson(itemList);
request.setAttribute("someObjectAsJson", someObjectAsJson);
затем в js (вместо метода ввода):
<script>var foo = ${someObjectAsJson};</script>
Примечание: EL в приведенном выше javascript работает, потому что вывод синтаксически допустим. Если вы не делаете строку первой в Java, вам нужно сделать это так:
<script>var foo = '${foo}';</script>