/ / Comment utiliser les servlets et Ajax? - java, ajax, jsp, servlets

Comment utiliser les servlets et Ajax? - java, ajax, jsp, servlets

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 l'appelle par le navigateur Web, il renvoie une nouvelle page contenant ce texte. Existe-t-il un moyen d'imprimer le texte de la page en cours à l'aide d'Ajax?

Réponses:

500 pour la réponse № 1

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

Comme c'est un joli fastidieux travailler pour le faire fonctionner sur tous les navigateurs(en particulier Internet Explorer par rapport à d'autres), il existe de nombreuses bibliothèques JavaScript qui simplifient cela dans des fonctions uniques et couvrent autant de bogues / bizarreries spécifiques au navigateur sous les hottes, telles que jQuery, Prototype, Mootools. Étant donné que jQuery est le plus populaire de nos jours, je vais l'utiliser dans les exemples ci-dessous.

Créer 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éez une servlet avec un doGet() méthode 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.
}

Mappez cette servlet sur un modèle d'URL de /someservlet ou /someservlet/* comme ci-dessous (évidemment, le modèle d'URL est libre de votre choix, mais vous "devez modifier la someservlet URL 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 page wiki Servlets):

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

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

Retour List<String> comme JSON

Avec JSON au lieu du texte en clair comme format de réponse, vous pouvezaller même plus loin. Il permet plus de dynamique. Tout d'abord, vous aimeriez avoir un outil pour convertir entre les objets Java et les chaînes JSON. Il y en a aussi beaucoup (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 /WEB-INF/lib dossier 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 la réponse sur application/json. Si vous oubliez de le définir ou si vous comptez sur une valeur par défaut de text/plain ou text/html, puis le responseJson l'argument ne vous donnerait pas un objet JSON, mais une chaîne vanille simple et vous auriez besoin de jouer manuellement avec JSON.parse() après, ce qui est donc totalement inutile si vous définissez le type de contenu en premier lieu.

Retour Map<String, String> comme 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>

Retour List<Entity> comme JSON

Voici un exemple qui affiche List<Product> dans un <table> où le Product la 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>.
});
});
});

Retour List<Entity> en XML

Voici un exemple qui fait effectivement la même chosecomme l'exemple précédent, mais 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 car vous pouvez réellement l'utiliser pour parcourir les résultats et effectuer un 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 <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 comprendrez probablement maintenant pourquoi XML est si importantplus puissant que JSON dans le but particulier de mettre à jour un document HTML à l'aide d'Ajax. JSON est drôle, mais après tout généralement utile uniquement pour les soi-disant «services Web publics». Les frameworks MVC comme JSF utilisez XML sous les couvertures pour leur magie ajax.

Ajaxification d'un formulaire existant

Vous pouvez utiliser jQuery $.serialize() pour ajuster facilement les formulaires POST existants sansjouer avec la collecte et le passage des paramètres d'entrée du formulaire individuel. En supposant un formulaire existant qui fonctionne parfaitement bien sans JavaScript / jQuery (et se dégrade donc gracieusement lorsque l'utilisateur final a désactivé JavaScript):

<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 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 plus ou moins la même chose que l'exemple jQuery ci-dessus, mais il a un support transparent supplémentaire pour multipart/form-data formulaires requis par les téléchargements de fichiers.

Envoi manuel des paramètres de requête à la servlet

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

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

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

Le même 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 à la servlet

Si vous avez toutefois l'intention d'envoyer l'objet JSON dans son ensemble au lieu de paramètres de demande individuels pour une raison quelconque, vous devez alors le sérialiser en une chaîne en utilisant JSON.stringify() (ne fait pas partie de jQuery) et demandez à jQuery de définir le type de contenu de la demande 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 effectuée 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 se mélangent contentType avec dataType. le contentType représente le type de demande corps. le dataType représente le type (attendu) du réponse corps, ce qui est généralement inutile car jQuery le détecte déjà automatiquement en fonction de la réponse Content-Type entête.

Ensuite, afin de traiter l'objet JSON dans leservlet qui n'est pas envoyé en tant que paramètres de demande 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 demande à l'aide d'un outil JSON au lieu d'utiliser getParameter() la manière habituelle. À savoir, les servlets ne prennent pas en charge application/json demandes formatées, mais seulement application/x-www-form-urlencoded ou multipart/form-data demandes formatées. 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 de simplement utiliser $.param(). Normalement, vous souhaitez utiliser JSON.stringify() uniquement si le service cible est par exemple un service JAX-RS (RESTful) qui, pour une raison quelconque, est uniquement capable de consommer des chaînes JSON et non des paramètres de requête réguliers.

Envoi d'une redirection depuis le servlet

Il est important de comprendre et de comprendre que tout sendRedirect() et forward() l'appel par le servlet sur une demande ajax ne ferait que transférer ou rediriger la demande ajax elle-même et non le document / fenêtre principal d'où provient la demande ajax. Dans ce cas, JavaScript / jQuery ne récupère que la réponse redirigée / transmise en tant que responseText variable 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, alors tout ce que vous pouvez faire est de remplacer le document actuel par lui.

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

Notez que cela ne modifie pas l'URL en tant qu'utilisateur finalvoit dans la barre d'adresse du navigateur. Il y a donc des problèmes de signet. 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 également:


12 pour la réponse № 2

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

Ce code est généralement javascript qui estinté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 de mettre en œuvre ce type dechose utilisant un plugin ou un module complémentaire de navigateur, 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 incorporé dans la page.)


10 pour la réponse № 3

Je vais vous montrer un exemple complet de servlet et comment appeler ajax.

Ici, nous allons créer l'exemple simple pour créer le formulaire de connexion à l'aide de 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 Ajax Sample

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

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

5 pour la réponse № 4
$.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);
}
});

5 pour la réponse № 5

Ajax (également AJAX) un acronyme pour asynchroneJavaScript et 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 Voici un exemple de code:

Fonction de script Java de page JSP pour soumettre des données à la 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 pouvez é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>");
}

3 pour la réponse № 6

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 est appelée Ajax.


3 pour la réponse № 7

Utiliser 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"
});}
}

Dans Servlet

request.getParameter("input")