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

Asked

Viewed 1,757 times

7

I have a web application using the Spring MVC framework.

I need to receive a List in a Javascript function, but I don’t know the best way to do this, without getting the code confused. The Processes 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 didn’t work:

In the script:

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

In the body:

<input type="hidden" id="lista" value='${processosList}'/>
  • 1

    When I need this type of functionality I return a JSON string and Javascript interprets it as an array naturally.

2 answers

6


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.

1

Dude, check out the Restcontroller, on it you can return your List and by JS, you receive with the AJAX, reading the result of the request.

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

I believe this passage 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>

The ideal would be for you to have one Service I would be called by that Controller, who in turn would call his DAO, but this way above should help you.

  • Explain your answer better.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.