Comment utiliser Servlets et Ajax?

je suis très nouveau pour 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. Y a-t-il un moyen d'imprimer le texte dans la page courante en utilisant Ajax?

295
demandé sur Taryn 2010-11-06 13:12:13

7 réponses

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

depuis qu'il est assez un fastidieux travail pour le faire fonctionner à travers tous les navigateurs (en particulier Internet Explorer versus autres), il existe de nombreuses bibliothèques JavaScript qui simplifie cela en une seule fonction et couvre autant de bugs/bizarreries spécifiques au navigateur que possible sous les capots, tels que jQuery , Prototype , Mootools . Depuis jQuery est plus populaire ces jours-ci, je vais l'utiliser dans les exemples ci-dessous.

exemple de coup d'envoi retournant String en clair

créer un /some.jsp comme ci-dessous (note: le code ne s'attend pas à ce que le fichier JSP soit placé dans un sous-dossier, si vous le faites, modifiez l'URL 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 ressemblent à 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.
}

mappez 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 aurez besoin de modifier l'URL someservlet dans les exemples de code JS

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

ou, si vous n'êtes pas encore sur un conteneur compatible Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc ou plus récent), puis cartographiez-le dans web.xml à l'ancienne (voir aussi nos Servlets wiki 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>

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

Retour "à la 1519300920" JSON

avec JSON au lieu de plaintext comme format de réponse, vous pouvez même obtenir quelques étapes plus loin. Il permet plus de dynamique. Tout d'abord, vous souhaitez avoir un outil pour convertir entre les objets Java et les chaînes JSON. Il y en a beaucoup aussi (voir le bas de cette page pour un aperçu). Mon préféré est Google Gson . Téléchargez et mettez son fichier JAR dans le dossier /WEB-INF/lib de votre webapplication.

Voici un exemple qui affiche List<String> comme <ul><li> . The 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 comme JSON et vous donne directement un objet JSON ( responseJson ) comme argument de fonction lorsque vous définissez la réponse type de contenu à application/json . Si vous oubliez de le définir ou de vous fier à un défaut de text/plain ou text/html , alors l'argument responseJson ne vous donnera pas un objet JSON, mais une simple chaîne vanille et vous aurez besoin de bidouiller manuellement avec JSON.parse() par la suite, ce qui est donc totalement inutile si vous définissez le type de contenu à la première place.

Retour "à la 1519400920" JSON

En 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>

Retour "à la 1519430920" JSON

voici un exemple qui affiche List<Product> dans un <table> où la classe Product a les propriétés Long id , String name et BigDecimal price . The 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>.
        });
    });
});

Retour "à la 1519430920" 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. En utilisant 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 au-dessus des résultats et effectuer le formatage de données côté serveur. The 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 (note: si vous mettez le <table> 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 réaliserez probablement maintenant 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 soi-disant "services web publics". MVC cadres comme JSF utiliser XML sous les couvertures pour leur magie ajax.

Ajaxifying un formulaire existant

vous pouvez utiliser jQuery $.serialize() pour ajaxifier facilement les formes de courrier existantes sans jouer avec la collecte et le passage des paramètres individuels d'entrée de forme. En supposant une forme existante qui fonctionne parfaitement bien sans JavaScript / jQuery (et se dégrade ainsi gracieusement quand l'utilisateur final a JavaScript handicapés):

<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 l'améliorer progressivement 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 distinguer 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 jQuery form plugin fait moins ou plus le même que ci-dessus jQuery exemple, mais il a le soutien transparent supplémentaire pour multipart/form-data formulaires comme exigé par téléchargement de fichiers.

envoi manuel des paramètres de la requête au servlet

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

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

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

la méthode doPost() décrite ci-dessus peut être réutilisée. Notez que la syntaxe ci-dessus fonctionne également avec $.get() en jQuery et doGet() en servlet.

envoi manuel d'un objet JSON à servlet

si toutefois vous avez l'intention d'envoyer l'objet JSON dans son ensemble plutôt que comme des paramètres de requête individuels pour une raison quelconque, alors vous devez le sérialiser à une chaîne en utilisant JSON.stringify() (ne fait pas partie de jQuery) et demander à jQuery de définir le type de contenu de la requête à application/json au lieu de (par défaut) application/x-www-form-urlencoded . Cela ne peut pas être fait via $.post() la 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) {
        // ...
    }
});

Ne remarque que beaucoup de débutants mix contentType avec dataType . Le contentType représente le type de l'organisme request . Le dataType représente le type (prévu) du réponse corps, qui est généralement inutile car jQuery l'autodétecte déjà basé sur l'en-tête Content-Type de la réponse.

ensuite, pour traiter l'objet JSON dans le servlet qui n'est pas envoyé en tant que paramètres de requête individuels mais comme une chaîne JSON entière de la manière ci-dessus, vous n'avez qu'à analyser manuellement le corps de la requête en utilisant un outil JSON au lieu d'utiliser getParameter() de la manière habituelle. Plus précisément, les servlets ne supportent pas 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 le parsing a JSON se transforme en 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 de simplement utiliser $.param() . Normalement, vous voulez utiliser JSON.stringify() seulement si le service cible est par exemple un service JAX-RS (RESTful) qui est pour une raison quelconque seulement capable de consommer des chaînes JSON et non des paramètres de requête réguliers.

envoyer une redirection de servlet

Important de réaliser et de comprendre est que toute sendRedirect() et forward() appel de la servlet sur une requête ajax serait seulement de l'avant ou de les rediriger de la requête ajax lui-même et non pas le document principal/de la fenêtre où la requête ajax à l'origine. JavaScript / jQuery ne récupérerait dans ce cas que la réponse redirigée/transmise comme variable responseText dans la fonction de rappel. Si cela représente une page HTML entière et non une réponse XML ou JSON spécifique à ajax, alors tout ce que vous pouvez faire est de remplacer la page actuelle document.

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

notez que cela ne change pas L'URL que enduser voit dans la barre d'adresse du navigateur. Il y a donc des problèmes avec la commercialisation des livres. Par conséquent, il est beaucoup mieux de simplement retourner une "instruction" pour JavaScript/jQuery pour effectuer une redirection au lieu de retourner tout le contenu de la page redirigée. Par exemple: en retournant 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
répondu 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 un certain code d'exécution dans le navigateur mettre à jour le DOM de la page.

ce code est typiquement javascript qui est incorporé ou lié à partir de la page HTML, d'où la suggestion D'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 de mettre en œuvre ce une sorte de chose utilisant un certain plugin de navigateur ou add-on, bien qu'il puisse être difficile pour un plugin d'atteindre dans les structures de données du navigateur pour mettre à jour le DOM. (Les plugins de code natifs écrivent normalement à un cadre graphique qui est intégré dans la page.)

13
répondu Stephen C 2014-02-16 22:40:36

je vais vous montrer un exemple entier de servlet & comment faire appel ajax.

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

de l'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 l'échantillon ajax

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

Loginservlet Servlet Code: -

    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
répondu 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
répondu SUBZ 2014-05-09 09:11:57

Ajax (aussi AJAX) est un acronyme pour Asynchronous JavaScript et XML. Avec Ajax, les applications web peuvent envoyer des données à un serveur et les récupérer de façon asynchrone. Voici un exemple de code:

page Jsp java script la fonction de soumettre des données à la servlet avec deux variable 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);

    }

envoyer les données à jsp en format xml (vous pouvez aussi utiliser du texte. Il vous suffit de changer le contenu de la réponse au 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
répondu 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 nouvelle page entière ou demande une mise à jour d'une partie d'une page existante. Cette technique s'appelle Ajax.

4
répondu Peter Knego 2010-11-06 10:30:37

utilisant bootstrap multi select

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'
    });}
}

Servlet

request.getParameter("input")
3
répondu Thakhani Tharage 2015-09-03 11:04:14