Comment utiliser les Servlets et Ajax?


Je suis très nouveau dans les applications Web et les Servlets et j'ai la question suivante:

Chaque fois que j'imprime quelque chose à l'intérieur du servlet et que je l'appelle par le webbrowser, il renvoie une nouvelle page contenant ce texte. Existe-t-il un moyen d'imprimer le texte dans la page actuelle en utilisant Ajax?

Author: Taryn, 2010-11-06

7 answers

En effet, le mot-clé est "ajax": JavaScript asynchrone et XML. Cependant, les dernières années, c'est plus que souvent JavaScript et JSON asynchrones. Fondamentalement, vous laissez JS exécuter une requête HTTP asynchrone et mettre à jour l'arborescence DOM HTML en fonction des données de réponse.

Comme c'est assez un fastidieux travail pour le faire fonctionner sur tous les navigateurs (en particulier Internet Explorer par rapport aux autres), il existe de nombreuses bibliothèques JavaScript qui simplifient cela dans les fonctions individuelles et couvre autant que possible un navigateur spécifique bugs/défauts sous le capot, comme jQuery, Prototype, Mootools. Puisque jQuery est le plus populaire de nos jours, je vais l'utiliser dans les exemples ci-dessous.

Exemple de Kickoff renvoyant {[23] } en texte brut

Créez un /some.jsp comme ci-dessous (remarque: le code ne s'attend pas à ce que le fichier JSP soit placé dans un sous-dossier, si vous le faites, modifiez l'URL du servlet en conséquence):

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>SO question 4112686</title>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>
            $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
                $.get("someservlet", function(responseText) {   // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response text...
                    $("#somediv").text(responseText);           // Locate HTML DOM element with ID "somediv" and set its text content with the response text.
                });
            });
        </script>
    </head>
    <body>
        <button id="somebutton">press here</button>
        <div id="somediv"></div>
    </body>
</html>

Créer un servlet avec une méthode doGet() qui ressemble à ceci:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String text = "some text";

    response.setContentType("text/plain");  // Set content type of the response so that jQuery knows what it can expect.
    response.setCharacterEncoding("UTF-8"); // You want world domination, huh?
    response.getWriter().write(text);       // Write response body.
}

Mapper ce servlet sur un modèle d'URL de /someservlet ou /someservlet/* comme ci-dessous (évidemment, le modèle d'URL est libre à votre choix, mais vous devrez modifier l'URL someservlet dans les exemples de code JS partout en conséquence):

@WebServlet("/someservlet/*")
public class SomeServlet extends HttpServlet {
    // ...
}

Ou, lorsque vous n'êtes pas encore sur un conteneur compatible Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc. ou plus récent), mappez-le dans web.xml à l'ancienne (voir aussi notre wiki Servlets page):

<servlet>
    <servlet-name>someservlet</servlet-name>
    <servlet-class>com.example.SomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>someservlet</servlet-name>
    <url-pattern>/someservlet/*</url-pattern>
</servlet-mapping>

Ouvrez maintenant le http://localhost:8080/context/test.jsp dans le navigateur et appuyez sur le bouton. Vous verrez que le contenu de la div est mis à jour avec la réponse du servlet.

Retournant List<String> en JSON

Avec JSON au lieu de texte en clair comme format de réponse, vous pouvez même aller plus loin. Cela permet plus de dynamique. Tout d'abord, vous souhaitez avoir un outil pour convertir entre les objets Java et les chaînes JSON. Il ya beaucoup de ainsi (voir en bas de cette page pour un aperçu). Mon préféré est Google Gson. Téléchargez et placez son fichier JAR dans le dossier /WEB-INF/lib de votre application Web.

Voici un exemple qui affiche List<String>, comme <ul><li>. Le servlet:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<String> list = new ArrayList<>();
    list.add("item1");
    list.add("item2");
    list.add("item3");
    String json = new Gson().toJson(list);

    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

Le code JS:

$(document).on("click", "#somebutton", function() {  // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
    $.get("someservlet", function(responseJson) {    // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON...
        var $ul = $("<ul>").appendTo($("#somediv")); // Create HTML <ul> element and append it to HTML DOM element with ID "somediv".
        $.each(responseJson, function(index, item) { // Iterate over the JSON array.
            $("<li>").text(item).appendTo($ul);      // Create HTML <li> element, set its text content with currently iterated item and append it to the <ul>.
        });
    });
});

Notez que jQuery analyse automatiquement la réponse en tant que JSON et vous donne directement un objet JSON (responseJson) comme argument de fonction lorsque vous définissez le type de contenu de réponse sur application/json. Si vous oubliez de le définir ou si vous vous fiez à une valeur par défaut de text/plain ou text/html, alors l'argument responseJson ne vous donnerait pas un objet JSON, mais une chaîne de vanille simple et vous auriez besoin de jouer manuellement avecJSON.parse() ensuite, ce qui est donc totalement inutile si vous définissez le type de contenu en premier lieu.

Retournant Map<String, String> en JSON

Voici un autre exemple qui affiche Map<String, String>, comme <option>:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Map<String, String> options = new LinkedHashMap<>();
    options.put("value1", "label1");
    options.put("value2", "label2");
    options.put("value3", "label3");
    String json = new Gson().toJson(options);

    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

Et le JSP:

$(document).on("click", "#somebutton", function() {               // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
    $.get("someservlet", function(responseJson) {                 // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON...
        var $select = $("#someselect");                           // Locate HTML DOM element with ID "someselect".
        $select.find("option").remove();                          // Find all child elements with tag name "option" and remove them (just to prevent duplicate options when button is pressed again).
        $.each(responseJson, function(key, value) {               // Iterate over the JSON object.
            $("<option>").val(key).text(value).appendTo($select); // Create HTML <option> element, set its value with currently iterated key and its text content with currently iterated item and finally append it to the <select>.
        });
    });
});

Avec

<select id="someselect"></select>

Retournant List<Entity> en JSON

Voici un exemple qui affiche List<Product> dans a <table>, la Product classe a les propriétés Long id, String name et BigDecimal price. Le servlet:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<Product> products = someProductService.list();
    String json = new Gson().toJson(products);

    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

Le code JS:

$(document).on("click", "#somebutton", function() {        // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
    $.get("someservlet", function(responseJson) {          // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON...
        var $table = $("<table>").appendTo($("#somediv")); // Create HTML <table> element and append it to HTML DOM element with ID "somediv".
        $.each(responseJson, function(index, product) {    // Iterate over the JSON array.
            $("<tr>").appendTo($table)                     // Create HTML <tr> element, set its text content with currently iterated item and append it to the <table>.
                .append($("<td>").text(product.id))        // Create HTML <td> element, set its text content with id of currently iterated product and append it to the <tr>.
                .append($("<td>").text(product.name))      // Create HTML <td> element, set its text content with name of currently iterated product and append it to the <tr>.
                .append($("<td>").text(product.price));    // Create HTML <td> element, set its text content with price of currently iterated product and append it to the <tr>.
        });
    });
});

Retournant List<Entity> en XML

Voici un exemple qui fait effectivement la même chose que l'exemple précédent, mais ensuite avec XML au lieu de JSON. Lorsque vous utilisez JSP comme générateur de sortie XML, vous verrez qu'il est moins fastidieux de coder la table et tout. JSTL est de cette façon, beaucoup plus utile que vous pouvez réellement l'utiliser pour itérer sur les résultats et effectuer le formatage des données côté serveur. Le servlet:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<Product> products = someProductService.list();

    request.setAttribute("products", products);
    request.getRequestDispatcher("/WEB-INF/xml/products.jsp").forward(request, response);
}

Le code JSP (remarque: si vous mettez le {[45] } dans un <jsp:include>, il peut être réutilisable ailleurs dans une réponse non-ajax):

<?xml version="1.0" encoding="UTF-8"?>
<%@page contentType="application/xml" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<data>
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.id}</td>
                <td><c:out value="${product.name}" /></td>
                <td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
            </tr>
        </c:forEach>
    </table>
</data>

Le code JS:

$(document).on("click", "#somebutton", function() {             // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
    $.get("someservlet", function(responseXml) {                // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response XML...
        $("#somediv").html($(responseXml).find("data").html()); // Parse XML, find <data> element and append its HTML to HTML DOM element with ID "somediv".
    });
});

Vous comprendrez probablement pourquoi XML est tellement plus puissant que JSON dans le but particulier de mettre à jour un document HTML en utilisant Ajax. JSON est drôle, mais après tout généralement seulement utile pour les soi-disant"services Web publics". Les frameworks MVC comme JSF utilisent XML sous les couvertures pour leur magie ajax.

Ajaxifier une forme existante

Vous pouvez utiliser jQuery $.serialize() pour ajaxifier facilement les formulaires POST existants sans manipuler la collecte et la transmission des paramètres d'entrée de formulaire individuels. En supposant un formulaire existant qui fonctionne parfaitement bien sans JavaScript / jQuery (et se dégrade donc gracieusement lorsque enduser a JavaScript désactivé):

<form id="someform" action="someservlet" method="post">
    <input type="text" name="foo" />
    <input type="text" name="bar" />
    <input type="text" name="baz" />
    <input type="submit" name="submit" value="Submit" />
</form>

Vous pouvez progressivement l'améliorer avec ajax comme ci-dessous:

$(document).on("submit", "#someform", function(event) {
    var $form = $(this);

    $.post($form.attr("action"), $form.serialize(), function(response) {
        // ...
    });

    event.preventDefault(); // Important! Prevents submitting the form.
});

Vous pouvez dans le servlet faire la distinction entre les requêtes normales et les requêtes ajax comme ci-dessous:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String foo = request.getParameter("foo");
    String bar = request.getParameter("bar");
    String baz = request.getParameter("baz");

    boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));

    // ...

    if (ajax) {
        // Handle ajax (JSON or XML) response.
    } else {
        // Handle regular (JSP) response.
    }
}

Le plugin jQuery Form fait moins ou plus la même chose que l'exemple jQuery ci-dessus, mais il a un support transparent supplémentaire pour les formulaires multipart/form-data comme requis par les téléchargements de fichiers.

Envoi manuel des paramètres de la demande au servlet

Si vous n'avez pas de formulaire du tout, mais je voulais juste interagir avec le servlet" en arrière-plan " par lequel vous souhaitez PUBLIER des données, alors vous pouvez utiliser jQuery $.param() pour convertir facilement un objet JSON en une chaîne de requête encodée en URL.

var params = {
    foo: "fooValue",
    bar: "barValue",
    baz: "bazValue"
};

$.post("someservlet", $.param(params), function(response) {
    // ...
});

La même méthode doPost() comme indiqué ci-dessus peut être réutilisée. Notez que la syntaxe ci-dessus fonctionne également avec $.get() dans jQuery et doGet() dans servlet.

Envoi manuel d'un objet JSON à un servlet

Si vous avez cependant l'intention d'envoyer l'objet JSON en tant que entier au lieu d'en tant que paramètres de demande individuels pour une raison quelconque, vous devrez alors le sérialiser en une chaîne en utilisant JSON.stringify() (ne fait pas partie de jQuery) et demande à jQuery de définir le type de contenu de la requête sur application/json au lieu de (par défaut) application/x-www-form-urlencoded. Cela ne peut pas être fait via $.post() fonction de commodité, mais doit être fait via $.ajax() comme ci-dessous.

var data = {
    foo: "fooValue",
    bar: "barValue",
    baz: "bazValue"
};

$.ajax({
    type: "POST",
    url: "someservlet",
    contentType: "application/json", // NOT dataType!
    data: JSON.stringify(data),
    success: function(response) {
        // ...
    }
});

Notez que beaucoup d'entrées mélangent contentType avec dataType. Le contentType représente le type du corpsrequest . Le dataType représente le type (attendu) du corps response, ce qui est généralement inutile car jQuery le détecte déjà automatiquement en fonction de l'en-tête Content-Type de response.

Ensuite, afin de traiter l'objet JSON dans le servlet qui n'est pas envoyé en tant que paramètres de requête individuels mais en tant que chaîne JSON entière de la manière ci-dessus, il vous suffit d'analyser manuellement le corps de la requête à l'aide d'un outil JSON au lieu d'utiliser getParameter() de la manière habituelle. À savoir, les servlets ne prennent pas en charge les requêtes formatées application/json , mais seulement les requêtes formatées application/x-www-form-urlencoded ou multipart/form-data. Gson prend également en charge l'analyse d'une chaîne JSON dans un objet JSON.

JsonObject data = new Gson().fromJson(request.getReader(), JsonObject.class);
String foo = data.get("foo").getAsString();
String bar = data.get("bar").getAsString();
String baz = data.get("baz").getAsString();
// ...

Notez que tout cela est plus maladroit que d'utiliser simplement $.param(). Normalement, vous ne souhaitez utiliser JSON.stringify() que si le service cible est par exemple un service JAX-RS (RESTful) qui, pour une raison quelconque, n'est capable que de consommer des chaînes JSON et non des paramètres de requête réguliers.

Envoi d'une redirection depuis un servlet

Il est important de réaliser et de comprendre que tout sendRedirect() et forward() l'appel par le servlet sur une requête ajax ne ferait que transférer ou redirigerla requête ajax elle-même et non le document/fenêtre principal d'où provient la requête ajax. JavaScript / jQuery ne récupérerait dans ce cas que la réponse redirigée/transférée en tant que variable responseText dans la fonction de rappel. S'il représente une page HTML entière et non une réponse XML ou JSON spécifique à ajax, tout ce que vous pouvez faire est de remplacer le document actuel par celui-ci.

document.open();
document.write(responseText);
document.close();

Notez que ceci ne change pas l'URL comme le voit l'utilisateur final dans la barre d'adresse du navigateur. Il y a donc des problèmes avec la bookmarkability. Par conséquent, il est préférable de simplement renvoyer une "instruction" pour que JavaScript/jQuery effectue une redirection au lieu de renvoyer tout le contenu de la page redirigée. Par exemple en renvoyant un booléen ou une URL.

String redirectURL = "http://example.com";

Map<String, String> data = new HashMap<>();
data.put("redirect", redirectURL);
String json = new Gson().toJson(data);

response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);

function(responseJson) {
    if (responseJson.redirect) {
        window.location = responseJson.redirect;
        return;
    }

    // ...
}

Voir aussi:

 510
Author: BalusC, 2017-05-23 12:18:18

La bonne façon de mettre à jour la page actuellement affichée dans le navigateur de l'utilisateur (sans la recharger) est d'avoir du code exécuté dans le navigateur pour mettre à jour le DOM de la page.

Ce code est généralement javascript qui est intégré ou lié à partir de la page HTML, d'où la suggestion AJAX. (En fait, si nous supposons que le texte mis à jour provient du serveur via une requête HTTP, c'est AJAX classique.)

Il est également possible d'implémenter ce genre de chose en utilisant un plugin de navigateur ou add-on, bien qu'il puisse être difficile pour un plugin d'accéder aux structures de données du navigateur pour mettre à jour le DOM. (Les plugins de code natif écrivent normalement dans un cadre graphique intégré à la page.)

 13
Author: Stephen C, 2014-02-16 22:40:36

Je vais vous montrer tout un exemple de servlet et comment ajax appelle-t-il.

Ici, nous allons créer l'exemple simple pour créer le formulaire de connexion en utilisant servlet.

Index.html

<form>  
   Name:<input type="text" name="username"/><br/><br/>  
   Password:<input type="password" name="userpass"/><br/><br/>  
   <input type="button" value="login"/>  
</form>  

Voici un exemple ajax

       $.ajax
        ({
            type: "POST",           
            data: 'LoginServlet='+name+'&name='+type+'&pass='+password,
            url: url,
        success:function(content)
        {
                $('#center').html(content);           
            }           
        });

Code de servlet LoginServlet :-

    package abc.servlet;

import java.io.File;


public class AuthenticationServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {   
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        try{
        HttpSession session = request.getSession();
        String username = request.getParameter("name");
        String password = request.getParameter("pass");

                /// Your Code
out.println("sucess / failer")
        } catch (Exception ex) {
            // System.err.println("Initial SessionFactory creation failed.");
            ex.printStackTrace();
            System.exit(0);
        } 
    }
}
 11
Author: Mitul Maheshwari, 2016-11-29 17:08:28
$.ajax({
type: "POST",
url: "url to hit on servelet",
data:   JSON.stringify(json),
dataType: "json",
success: function(response){
    // we have the response
    if(response.status == "SUCCESS"){
        $('#info').html("Info  has been added to the list successfully.<br>"+
        "The  Details are as follws : <br> Name : ");

    }else{
        $('#info').html("Sorry, there is some thing wrong with the data provided.");
    }
},
 error: function(e){
   alert('Error: ' + e);
 }
});
 6
Author: SUBZ, 2014-05-09 09:11:57

Ajax (également AJAX) un acronyme pour Asynchronous JavaScript and XML) est un groupe de techniques de développement Web interdépendantes utilisées côté client pour créer des applications Web asynchrones. Avec Ajax, les applications Web peuvent envoyer des données à un serveur et les récupérer de manière asynchrone Ci-dessous est un exemple de code:

Jsp page java script fonction pour soumettre des données à servlet avec deux variables FirstName et LastName:

function onChangeSubmitCallWebServiceAJAX()
    {
      createXmlHttpRequest();
      var firstName=document.getElementById("firstName").value;
      var lastName=document.getElementById("lastName").value;
      xmlHttp.open("GET","/AJAXServletCallSample/AjaxServlet?firstName="
      +firstName+"&lastName="+lastName,true)
      xmlHttp.onreadystatechange=handleStateChange;
      xmlHttp.send(null);

    }

Servlet pour lire les données renvoyées à jsp au format xml (Vous pourrait également utiliser du texte. Il vous suffit de changer le contenu de la réponse en texte et de rendre les données sur la fonction javascript.)

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String firstName = request.getParameter("firstName");
    String lastName = request.getParameter("lastName");

    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("<details>");
    response.getWriter().write("<firstName>"+firstName+"</firstName>");
    response.getWriter().write("<lastName>"+lastName+"</lastName>");
    response.getWriter().write("</details>");
}
 6
Author: user3468976, 2014-07-02 22:09:12

Normalement, vous ne pouvez pas mettre à jour une page à partir d'un servlet. Le client (navigateur) doit demander une mise à jour. Le client Eiter charge une toute nouvelle page ou demande une mise à jour d'une partie d'une page existante. Cette technique s'appelle Ajax.

 4
Author: Peter Knego, 2010-11-06 10:30:37

Utilisation de la sélection multiple bootstrap

Ajax

function() { $.ajax({
    type : "get",
    url : "OperatorController",
    data : "input=" + $('#province').val(),
    success : function(msg) {
    var arrayOfObjects = eval(msg); 
    $("#operators").multiselect('dataprovider',
    arrayOfObjects);
    // $('#output').append(obj);
    },
    dataType : 'text'
    });}
}

Dans le servlet

request.getParameter("input")
 3
Author: Thakhani Tharage, 2015-09-03 11:04:14