Bonjour à tous.
Je vous expose mon cas : J'ai une appli web qui permet à l'utilisateur de saisir un mot et de cliquer sur un bouton de recherche. Lorsque cette action est lancée (depuis une jsp donc) j'appel ma servlet qui va parcourir l'ensemble des fichiers à partir de la racine de mon serveur puis lire leur contenu et chercher si le mot saisi est contenu dans le fichier ou non.
Je récupère la liste des fichiers remplissant cette condition que je retourne à ma page, et un script AJAX se charge alors d'afficher, entre autre, le nom des fichiers trouvés dans un tableau.
Mon problème, c'est qu'à l'heure actuelle, le tableau s'affiche en "une fois", c'est-à-dire une fois que tous les fichiers ont été parcourus côté serveur et renvoyés côté client. Ce que j'aimerais, c'est que le tableau se remplisse progressivement, c'est-à-dire à chaque fois qu'un fichier est trouvé au niveau de l'itération de ma servlet, on envoi le résultat à la page et le tableau se remplit alors au fur et à mesure.
Voici le code de ma servlet (et particulièrement la partie itération) :
Vous remarquerez que j'envoi une réponse au format XML et par l'intermédiaire d'un StringBuilder (output dans le code précédent) et c'est après avoir totalement remplit ce format de sortie que j'envoi le tout au XMLHttpResponse.PrintWriter.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Getting the name of the desired word. wordToSearch = request.getParameter("wordName"); // Getting the context path. contextPath = request.getServletContext().getRealPath(File.separator); // Creating the output format. response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Request-Method", "GET"); response.setContentType("text/xml"); output = new StringBuilder(); output.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); output.append("<searchResults>\n"); // If the input word name isn't empty, the algorithm is launched. if (null != wordToSearch && !"".equals(wordToSearch)) { lstFiles.clear(); searching(new File(contextPath), wordToSearch); int n = lstFiles.size(); // Priting a message that indicate how many files have been found with the word to search. emptyFieldMessage = n + " files has been found containing the word '" + wordToSearch + "'!"; output.append("<message>").append(emptyFieldMessage).append("</message>\n"); output.append("<lstFiles>\n"); // Then, files list with : // - File path in "name" parameter, // - Number of apparence of the word in "nb" parameter, // - Formatted path as the value. for(int i = 0; i < n; i++) { output.append("<file name=\"" + lstFiles.get(i) + "\" nb=\"" + lstNbApparence.get(i) + "\" >").append(lstFilesPath.get(i)).append("</file>\n"); } output.append("</lstFiles>\n"); } // If the input word is empty, then we print an error message. else { emptyFieldMessage = "Please write an none empty word!"; output.append("<message>").append(emptyFieldMessage).append("</message>"); } // To end the procedure, we write our output to the PrintWriter. output.append("</searchResults>"); response.getWriter().write(output.toString()); }
C'est pour cela que je me demande si mon objectif est réalisable. Comment envoyer progressivement les données côté client si le fichier XML est en cours de construction?
Pour info également, le script de ma jsp :
Rien de plus classique, une fonction request avec un callback qui surveille l'état du XMLHttpRequest + une fonction de lecture de la réponse, où vous pouvez voir la construction du tableau de manière itérative. On voit bien ici que le tableau est remplit intégralement avant d'être envoyé à la div "file".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 <script> // Creating xhr variable. var xhr = null; // Creating the "Search" button function. function request(callback) { // "Cancel" button case. if (xhr && xhr.readyState != 0) { xhr.abort(); } // "Search" button case. else { // Calling the good function from external file. xhr = getXMLHttpRequest(); // Callback and loading icon management. xhr.onreadystatechange = function() { if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) { callback(xhr.responseXML); document.getElementById("loader").style.display = "none"; document.getElementById("btn").value = "Search"; } else if (xhr.readyState < 3) { document.getElementById("loader").style.display = "inline"; document.getElementById("btn").value = "Cancel"; } }; // Calling the Servlet in charge of the recursion algorithm. var input = encodeURIComponent(document.getElementById("wordName").value); xhr.open("GET", "/webApp_Search_Merge/ActionServlet?wordName=" + input, true); xhr.send(null); } } // Creating the reponse function. function readData(response) { if (null != response) { // Posting the message include in the XML file sending back by the Servlet. var message = response.getElementsByTagName("message"); document.getElementById("message").innerHTML = message[0].firstChild.nodeValue; // Posting founded files in a table. var files = response.getElementsByTagName("file"); // -> Creating the results table. var table = "<table width=\"100%\">\n"; for (var i = 0, c = files.length; i < c; i++) { // -> Building the number of apparence in each file. var nb = files[i].getAttribute("nb"); var nbSentence = ""; if (nb == 1) { nbSentence = nb + " time in this file."; } else { nbSentence = nb + " times in this file."; } // Building and filling the table. if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=\"" + files[i].firstChild.nodeValue + "\" target=\"_blank\" >" + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; } else { table += "<tr class=\"impair\"><td><a href=\"" + files[i].firstChild.nodeValue + "\" target=\"_blank\" >" + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; } } table += "</table>\n"; // -> To end the procedure, we had the table to the right div. document.getElementById("files").innerHTML = table; } } </script>
Quelqu'un aurait'il déjà rencontré ce problème ? A une idée ?
Merci d'avance pour votre aide, Thomas.
Partager