Current problem
The code will not work because the value of ${processosList}
will not be a list that Javascript understands, but the list representation in a String
returned by your method toString
.
The method toSting
of ArrayList
, for example, returns something like:
[elemento1.toString(), elemento2.toString(), ...]
If the class Processo
does not implement the method toString
, the result will be:
[Processo@872789, Processo@9721768, ...]
One solution would be to implement the toString
of Processo
to return something significant, perhaps the object ID or any other information that is needed in Javascript. Then you would have something like:
[10, 11, ...]
Even so, your Javascript code is not recovering the value of the hidden field. The id
of an HTML element has nothing to do with the variables you use in the code.
And, anyway, rely on the return of the method toString
from a list is not recommended, as there are several types of lists in Java and the implementation used in the system may change causing unwanted side effects.
Understanding the JSP
It seems to me a common confusion to think that somehow the JSP or any template engine running on the server understands or communicates directly with the Javascript that will be running on the client.
In fact, when JSP runs it understands plain text only. It doesn’t matter if an HTML tag or even if Javascript code is correct or not.
A JSP simply sends a handful of text to the browser. This, in turn, interprets the text according to the rules of HTML, Javascript, CSS or corresponding technology.
Therefore, your goal within a JSP is to generate a coherent text output. Never think that a Java variable will somehow magically end up being read directly by a script. After all, all the user’s browser sees is a static page composed of text.
Solution
Now that we know we need to convert the list into some text format to write to JSP, we can think of several possibilities:
Turning the list into a String
in the Java code
This can be done using the method toString
already mentioned, a custom method to concatenate the list elements into a String
or even a library that generates XML or JSON.
Particularly, I would prefer to use JSON because it is a Javascript-compatible standard and a standard in fact of modern web applications.
Using the Jackson library, for example, converting an object into a list can be as simple as this:
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(lista);
Note, however, that all objects in the list will also be serialized in String
. So depending on the complexity of the object this may not be desired.
Assuming, however, that the list items have some simple properties, the result of the above code could be something like:
[{id: 10, titulo: "Titulo 1"}, {id: 11, titulo: "Titulo 2"}, ...]
If you just need a simple value like a id
, can implement your own routine so:
String str = lista.stream()
.map(processo -> Integer.toString(processo.getId()))
.collect(Collectors.joining(",", "[", "]"));
This will return a string like this:
[10, 11, ...]
Regardless of how you do it, you can now print the generated content directly within a tag <script>
. For example, in your controller you would put the String in an attribute:
mav.addObject("processos", str);
And in JSP the String would be replaced directly in the script:
var lista = ${processos};
The result when the browser receives the page would be something like:
var lista = [10, 11, ...];
Print list elements individually to JSP
Another approach is not to format the values directly in Java, but to write this in JSP.
Example:
<c:forEach items="${processosList}" var="p">
<input type="hidden" class="item-processo" value="<c:out value="${p.id}">" />
</c:forEach>
This will generate something like:
<input type="hidden" class="item-processo" value="10" />
<input type="hidden" class="item-processo" value="11" />
<input type="hidden" class="item-processo" value="..." />
Then you can go through the elements with the method getElementsByClassName
.
Another alternative would be to do directly in Javascript:
var lista = [];
<c:forEach items="${processosList}" var="p">
fruits.push(<c:out value="${p.id}">);
</c:forEach>
That would generate something like this:
var lista = [];
fruits.push(10);
fruits.push(11);
fruits.push(...);
Considerations
Anyway, as I said, there are several ways including several that I didn’t mention.
The best depends exactly on what you will do with this information.
When I need this type of functionality I return a JSON string and Javascript interprets it as an array naturally.
– cantoni