How to receive a List (Java) in Javascript using Spring MVC?

7

I have a web application where the Spring MVC framework is being used.

I need to get a List in a Javascript function, but I do not know how best to do this without leaving the code confusing. The Process class has String and Integer attributes.

My Controller sends the List to jsp as follows:

ModelAndView mav = new ModelAndView("relatorios");
List<Processo> processosList = processoDAO.listProcessosAtivos();
mav.addObject("processosList", processosList);

The question is: how to receive and use this list in a javascript function? I tried to use it as follows but it did not work:

No script:

var lista = [];
lista = document.getElementById("lista");

No body:

<input type="hidden" id="lista" value='${processosList}'/>
    
asked by anonymous 24.11.2015 / 20:45

2 answers

6

Current issue

The code will not work because the value of ${processosList} will not be a list that JavaScript understands, but the representation of the list in a String returned by its toString method.

The toSting of ArrayList method, for example, returns something like:

[elemento1.toString(), elemento2.toString(), ...]

If the Processo class does not implement the toString method, the result will be:

[Processo@872789, Processo@9721768, ...]

One solution would be to implement toString of Processo to return something significant, perhaps the object ID or any other information that JavaScript requires. Then you would have something like:

[10, 11, ...]

Even so, your JavaScript code is not retrieving the value of the hidden field. id of an HTML element has nothing to do with the variables you use in the code.

And anyway, relying on the return of the toString method of a list is not recommendable, as there are several list types in Java and the implementation used in the system may change causing unwanted side effects.

Understanding the JSP

I find it a common mess to think that somehow the JSP or any template engine running on the server understands or communicates directly with the JavaScript that is going to run on the client.

In fact, when the JSP is run it understands pure text only. It does not matter whether an HTML tag or even whether the 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 text output that is consistent. Never think that a Java variable will, in any way magical, end up being read directly by a script. In the end, everything the user's browser sees is a static page made up of text.

Solution

Now that we know we need to convert the list to some text format to write in the JSP, we can think of several possibilities:

Transform the list into a String in Java code

This can be done using the toString method already mentioned, a custom method to concatenate list elements in a String or even a library that generates XML or JSON.

In particular, I would prefer to use JSON as a JavaScript compliant standard and a de facto standard for 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 items in the list 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 only need a simple value like id , you can implement your own routine like this:

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 inside a <script> tag. For example, in your controller you would put the String in an attribute:

mav.addObject("processos", str);

And in the 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 the list elements individually in the JSP

Another approach is not to do the formatting of values directly in Java, but to write this in the 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 loop through the elements using the getElementsByClassName method.

Another alternative would be to do it directly in JavaScript:

var lista = [];
<c:forEach items="${processosList}" var="p">
fruits.push(<c:out value="${p.id}">);
</c:forEach>

This 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 did not mention.

The best depends exactly on what you are going to do with this information.

    
25.11.2015 / 06:51
1

Dude, take a look at the RESTController , where you can return your List and by JS , you get with the AJAX , reading the result of the request.

After you read the request, you can add the data to a Array and use it normally in your JS .

I think this section can help you:

@RestController
public class SeuController {

    @RequestMapping("/getRelatorios")
    public List<Processo> getRelatorio() throws Exception {
        List<Processo> processosList = processoDAO.listProcessosAtivos();

        return processosList;
    }
}

Already in your JS, you could use something like this:

<script>
    var relatorios = [];

    $.ajax({
        url: '<c:url value="/getRelatorios"/>',
        type: 'GET',
        success: function(data) {
            for(var i = 0; i < data.length; i++){
                relatorios.push(data[i]);
            }
        }
    });
</script>

Ideally you would have a Service I would be called by this Controller , which in turn would call your DAO , however this way above should help you.

    
20.09.2018 / 19:20