/ / Wie benutzt man Servlets und Ajax? - Java, Ajax, JSP, Servlets

Wie benutzt man Servlets und Ajax? - Java, Ajax, JSP, Servlets

Ich bin sehr neu in Web-Apps und Servlets und habe die folgende Frage:

Immer wenn ich etwas im Servlet drucke und es vom Webbrowser aufrufe, wird eine neue Seite mit diesem Text zurückgegeben. Gibt es eine Möglichkeit, den Text auf der aktuellen Seite mit Ajax zu drucken?

Antworten:

500 für Antwort № 1

In der Tat ist das Schlüsselwort "Ajax": Asynchrones JavaScript und XML. In den letzten Jahren ist es jedoch mehr als oft Asynchrones JavaScript und JSON. Grundsätzlich lassen Sie JS eine asynchrone HTTP-Anforderung ausführen und den HTML-DOM-Baum basierend auf den Antwortdaten aktualisieren.

Da ist es ziemlich a langweilig arbeiten, damit es in allen Browsern funktioniert(insbesondere Internet Explorer im Vergleich zu anderen), es gibt viele JavaScript-Bibliotheken, die dies in einzelnen Funktionen vereinfachen und so viele browserspezifische Fehler / Macken wie möglich abdecken jQuery, Prototyp, Mootools. Da jQuery heutzutage am beliebtesten ist, werde ich es in den folgenden Beispielen verwenden.

Ein ... kreieren /some.jsp wie unten (Hinweis: Der Code erwartet nicht, dass die JSP-Datei in einem Unterordner abgelegt wird. Wenn Sie dies tun, ändern Sie die Servlet-URL entsprechend):

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

Erstellen Sie ein Servlet mit a doGet() Methode, die so aussieht:

@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.
}

Ordnen Sie dieses Servlet einem URL-Muster von zu /someservlet oder /someservlet/* wie unten (natürlich ist das URL-Muster frei von Ihrer Wahl, aber Sie müssten das ändern someservlet URL in JS-Codebeispielen über alle Stellen entsprechend):

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

Wenn Sie sich noch nicht in einem Servlet 3.0-kompatiblen Container befinden (Tomcat 7, Glassfish 3, JBoss AS 6 usw. oder neuer), ordnen Sie ihn zu web.xml die altmodische Art (siehe auch unsere Servlets Wiki-Seite):

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

Jetzt öffne die http://localhost:8080/context/test.jsp im Browser und drücken Sie die Taste. Sie werden sehen, dass der Inhalt des div mit der Servlet-Antwort aktualisiert wird.

Rückkehr List<String> als JSON

Mit JSON anstelle von Klartext als Antwortformat können Siesogar noch ein paar Schritte weiter. Es ermöglicht mehr Dynamik. Zunächst möchten Sie ein Tool zum Konvertieren zwischen Java-Objekten und JSON-Zeichenfolgen haben. Es gibt auch viele davon (siehe unten) diese Seite für eine Übersicht). Mein persönlicher Favorit ist Google Gson. Laden Sie die JAR-Datei herunter und legen Sie sie dort ab /WEB-INF/lib Ordner Ihrer Webanwendung.

Hier ist ein Beispiel, das angezeigt wird List<String> wie <ul><li>. Das 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);
}

Der JS-Code:

$(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>.
});
});
});

Beachten Sie, dass jQuery die Antwort automatisch als JSON analysiert und Ihnen direkt ein JSON-Objekt gibt (responseJson) als Funktionsargument, wenn Sie den Inhaltstyp der Antwort auf setzen application/json. Wenn Sie vergessen, es festzulegen, oder sich auf einen Standardwert von verlassen text/plain oder text/html, dann ist die responseJson Das Argument würde Ihnen kein JSON-Objekt geben, sondern eine einfache Vanille-Zeichenfolge, und Sie müssten manuell damit herumspielen JSON.parse() danach, was also völlig unnötig ist, wenn Sie den Inhaltstyp an erster Stelle richtig einstellen.

Rückkehr Map<String, String> als JSON

Hier ist ein weiteres Beispiel, das angezeigt wird Map<String, String> wie <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);
}

Und die 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>.
});
});
});

mit

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

Rückkehr List<Entity> als JSON

Hier ist ein Beispiel, das angezeigt wird List<Product> in einem <table> bei dem die Product Klasse hat die Eigenschaften Long id, String name und BigDecimal price. Das 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);
}

Der JS-Code:

$(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>.
});
});
});

Rückkehr List<Entity> als XML

Hier ist ein Beispiel, das effektiv dasselbe tutwie im vorherigen Beispiel, aber dann mit XML anstelle von JSON. Wenn Sie JSP als XML-Ausgabegenerator verwenden, werden Sie feststellen, dass es weniger mühsam ist, die Tabelle und alle zu codieren. JSTL ist auf diese Weise viel hilfreicher, da Sie es tatsächlich verwenden können, um die Ergebnisse zu durchlaufen und die serverseitige Datenformatierung durchzuführen. Das 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);
}

Der JSP-Code (Hinweis: Wenn Sie den <table> in einem <jsp:include>kann es an anderer Stelle in einer Nicht-Ajax-Antwort wiederverwendbar sein):

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

Der JS-Code:

$(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".
});
});

Sie werden jetzt wahrscheinlich erkennen, warum XML so viel istLeistungsstärker als JSON für den speziellen Zweck der Aktualisierung eines HTML-Dokuments mit Ajax. JSON ist lustig, aber im Allgemeinen nur für sogenannte "öffentliche Webdienste" nützlich. MVC-Frameworks mögen JSF Verwenden Sie XML unter der Decke für ihre Ajax-Magie.

Ajaxifizierung eines vorhandenen Formulars

Sie können jQuery verwenden $.serialize() bestehende POST-Formulare ohne zu vereinfachenHerumspielen mit dem Sammeln und Übergeben der einzelnen Formulareingabeparameter. Angenommen, ein vorhandenes Formular funktioniert ohne JavaScript / jQuery einwandfrei (und verschlechtert sich daher ordnungsgemäß, wenn der Endbenutzer JavaScript deaktiviert hat):

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

Sie können es mit Ajax wie folgt schrittweise verbessern:

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

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

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

Sie können im Servlet wie folgt zwischen normalen Anforderungen und Ajax-Anforderungen unterscheiden:

@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.
}
}

Das jQuery Form Plugin macht weniger oder mehr das gleiche wie im obigen jQuery-Beispiel, bietet jedoch zusätzliche transparente Unterstützung für multipart/form-data Formulare gemäß Datei-Uploads.

Manuelles Senden von Anforderungsparametern an das Servlet

Wenn Sie überhaupt kein Formular haben, sondern nur mit dem Servlet interagieren möchten, "im Hintergrund", wobei Sie einige Daten veröffentlichen möchten, können Sie jQuery verwenden $.param() um ein JSON-Objekt einfach in eine URL-codierte Abfragezeichenfolge zu konvertieren.

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

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

Das Gleiche doPost() Methode wie hier oben gezeigt kann wiederverwendet werden. Beachten Sie, dass die obige Syntax auch mit funktioniert $.get() in jQuery und doGet() im Servlet.

Manuelles Senden des JSON-Objekts an das Servlet

Wenn Sie jedoch aus irgendeinem Grund beabsichtigen, das JSON-Objekt als Ganzes anstatt als einzelne Anforderungsparameter zu senden, müssen Sie es mithilfe von in eine Zeichenfolge serialisieren JSON.stringify() (nicht Teil von jQuery) und weisen Sie jQuery an, den Anforderungsinhaltstyp auf festzulegen application/json anstelle von (Standard) application/x-www-form-urlencoded. Dies kann nicht über erfolgen $.post() Komfortfunktion, muss aber über erfolgen $.ajax() wie nachstehend.

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) {
// ...
}
});

Beachten Sie, dass sich viele Vorspeisen mischen contentType mit dataType. Das contentType repräsentiert den Typ der anfordern Körper. Das dataType repräsentiert den (erwarteten) Typ des Antwort body, was normalerweise nicht erforderlich ist, da jQuery es bereits anhand der Antwort automatisch erkennt Content-Type Header.

Dann, um das JSON-Objekt in der zu verarbeitenServlet, das nicht als einzelne Anforderungsparameter gesendet wird, sondern als ganze JSON-Zeichenfolge auf die oben beschriebene Weise. Sie müssen den Anforderungshauptteil nur manuell mit einem JSON-Tool analysieren, anstatt ihn zu verwenden getParameter() der übliche Weg. Servlets unterstützen nämlich nicht application/json formatierte Anfragen, aber nur application/x-www-form-urlencoded oder multipart/form-data formatierte Anfragen. Gson unterstützt auch das Parsen einer JSON-Zeichenfolge in ein JSON-Objekt.

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();
// ...

Beachten Sie, dass dies alles ungeschickter ist als nur zu verwenden $.param(). Normalerweise möchten Sie verwenden JSON.stringify() nur wenn der Zieldienst z.B. Ein JAX-RS-Dienst (RESTful), der aus irgendeinem Grund nur JSON-Zeichenfolgen und keine regulären Anforderungsparameter verarbeiten kann.

Senden einer Weiterleitung vom Servlet

Wichtig zu erkennen und zu verstehen ist, dass alle sendRedirect() und forward() Ein Aufruf des Servlets auf eine Ajax-Anfrage würde nur weiterleiten oder umleiten die Ajax-Anfrage selbst und nicht das Hauptdokument / Fenster, aus dem die Ajax-Anfrage stammt. JavaScript / jQuery würde in diesem Fall nur die umgeleitete / weitergeleitete Antwort als abrufen responseText Variable in der Rückruffunktion. Wenn es sich um eine ganze HTML-Seite und nicht um eine Ajax-spezifische XML- oder JSON-Antwort handelt, können Sie lediglich das aktuelle Dokument durch dieses ersetzen.

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

Beachten Sie, dass dies die URL als Endbenutzer nicht ändertwird in der Adressleiste des Browsers angezeigt. Es gibt also Probleme mit der Lesezeichenfähigkeit. Daher ist es viel besser, nur eine "Anweisung" für JavaScript / jQuery zurückzugeben, um eine Umleitung durchzuführen, anstatt den gesamten Inhalt der umgeleiteten Seite zurückzugeben. Z.B. durch Rückgabe eines Booleschen Werts oder einer 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;
}

// ...
}

Siehe auch:


12 für die Antwort № 2

Der richtige Weg, um die aktuell im Browser des Benutzers angezeigte Seite zu aktualisieren (ohne sie neu zu laden), besteht darin, dass im Browser Code ausgeführt wird, der das DOM der Seite aktualisiert.

Dieser Code ist normalerweise Javascripteingebettet in oder verlinkt von der HTML-Seite, daher der AJAX-Vorschlag. (Wenn wir davon ausgehen, dass der aktualisierte Text über eine HTTP-Anforderung vom Server stammt, handelt es sich um klassisches AJAX.)

Es ist auch möglich, diese Art von zu implementierenVerwenden eines Browser-Plugins oder eines Add-Ons, obwohl es für ein Plugin schwierig sein kann, in die Datenstrukturen des Browsers zu gelangen, um das DOM zu aktualisieren. (Native Code-Plugins schreiben normalerweise in einen Grafikrahmen, der in die Seite eingebettet ist.)


10 für die Antwort № 3

Ich werde Ihnen ein ganzes Beispiel für Servlet zeigen und wie man Ajax aufruft.

Hier erstellen wir ein einfaches Beispiel zum Erstellen des Anmeldeformulars mithilfe eines Servlets.

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>

Hier ist ein Ajax-Beispiel

       $.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);
}
}
}

5 für die Antwort № 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 für die Antwort № 5

Ajax (auch AJAX) ist eine Abkürzung für AsynchronousJavaScript und XML) ist eine Gruppe miteinander verbundener Webentwicklungstechniken, die auf der Clientseite zum Erstellen asynchroner Webanwendungen verwendet werden. Mit Ajax können Webanwendungen Daten asynchron an einen Server senden und von diesem abrufen Unten ist ein Beispielcode:

Java-Skriptfunktion für Jsp-Seiten zum Senden von Daten an das Servlet mit zwei Variablen Vorname und Nachname:

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 zum Lesen von Daten, die im XML-Format an JSP zurückgesendet werden (Sie können auch Text verwenden. Sie müssen lediglich den Antwortinhalt in Text ändern und Daten in der Javascript-Funktion rendern.)

/**
* @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 für die Antwort № 6

Normalerweise können Sie eine Seite von einem Servlet nicht aktualisieren. Der Client (Browser) muss ein Update anfordern. Der Eiter-Client lädt eine ganz neue Seite oder fordert eine Aktualisierung eines Teils einer vorhandenen Seite an. Diese Technik heißt Ajax.


3 für die Antwort № 7

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

In Servlet

request.getParameter("input")