/ / Jak korzystać z serwletów i Ajax? - java, ajax, jsp, serwlety

Jak korzystać z serwletów i Ajax? - java, ajax, jsp, serwlety

Jestem bardzo nowy w aplikacjach internetowych i serwletach i mam następujące pytanie:

Ilekroć drukuję coś wewnątrz serwletu i wywołuję go przez przeglądarkę internetową, zwraca nową stronę zawierającą ten tekst. Czy istnieje sposób wydrukowania tekstu na bieżącej stronie za pomocą Ajax?

Odpowiedzi:

500 za odpowiedź nr 1

Rzeczywiście, słowem kluczowym jest „ajax”: Asynchroniczny JavaScript i XML. Jednak w ostatnich latach jest to więcej niż często Asynchroniczny JavaScript i JSON. Zasadniczo pozwalasz JS wykonać asynchroniczne żądanie HTTP i aktualizujesz drzewo DOM HTML na podstawie danych odpowiedzi.

Ponieważ to jest całkiem nudny pracować, aby działał we wszystkich przeglądarkach(zwłaszcza Internet Explorer w porównaniu z innymi), istnieje wiele bibliotek JavaScript, które upraszczają to w pojedynczych funkcjach i obejmują tak wiele, jak to możliwe, specyficznych dla przeglądarki błędów / dziwactw pod maską, takich jak jQuery, Prototyp, Mootools. Ponieważ jQuery jest obecnie najbardziej popularny, użyję go w poniższych przykładach.

Stwórz /some.jsp jak poniżej (uwaga: kod nie oczekuje umieszczenia pliku JSP w podfolderze, jeśli to zrobisz, odpowiednio zmień adres URL serwletu):

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

Utwórz serwlet za pomocą doGet() metoda, która wygląda następująco:

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

Odwzoruj ten serwlet na wzorcu adresu URL /someservlet lub /someservlet/* jak poniżej (oczywiście wzorzec adresu URL jest dowolny do wyboru, ale trzeba by zmienić someservlet Adres URL w przykładach kodu JS we wszystkich miejscach odpowiednio):

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

Lub, jeśli nie masz jeszcze kontenera zgodnego z serwletem 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6 itp. Lub nowszy), a następnie zamapuj go w web.xml staroświecki sposób (patrz także nasza strona wiki serwletów):

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

Teraz otwórz http://localhost:8080/context/test.jsp w przeglądarce i naciśnij przycisk. Zobaczysz, że zawartość div zostanie zaktualizowana o odpowiedź serwletu.

Powracający List<String> jak JSON

Z JSON zamiast zwykłego tekstu jako formatu odpowiedzi, możesznawet kilka kroków dalej. Pozwala na większą dynamikę. Po pierwsze, chciałbyś mieć narzędzie do konwersji między obiektami Java i łańcuchami JSON. Jest ich również mnóstwo (patrz na dole ta strona przegląd). Moim osobistym faworytem jest Google Gson. Pobierz i umieść plik JAR w /WEB-INF/lib folder twojej aplikacji internetowej.

Oto przykład, który się wyświetla List<String> tak jak <ul><li>. Serwlet:

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

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

Zauważ, że jQuery automatycznie analizuje odpowiedź jako JSON i daje ci bezpośrednio obiekt JSON (responseJson) jako argument funkcji po ustawieniu typu treści odpowiedzi na application/json. Jeśli zapomnisz go ustawić lub polegasz na domyślnej wartości text/plain lub text/html, a później responseJson argument nie dałby ci obiektu JSON, ale zwykły ciąg waniliowy i musisz ręcznie manipulować JSON.parse() później, co jest całkowicie niepotrzebne, jeśli typ zawartości zostanie ustawiony na pierwszym miejscu.

Powracający Map<String, String> jak JSON

Oto kolejny przykład, który się wyświetla Map<String, String> tak jak <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);
}

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

z

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

Powracający List<Entity> jak JSON

Oto przykład, który się wyświetla List<Product> w <table> gdzie Product klasa ma właściwości Long id, String name i BigDecimal price. Serwlet:

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

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

Powracający List<Entity> jako XML

Oto przykład, który robi to samojak w poprzednim przykładzie, ale z XML zamiast JSON. Gdy używasz JSP jako generatora danych wyjściowych XML, zobaczysz, że mniej uciążliwe jest kodowanie tabeli i wszystkich innych. JSTL jest w ten sposób o wiele bardziej pomocny, ponieważ można go używać do iteracji wyników i formatowania danych po stronie serwera. Serwlet:

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

Kod JSP (uwaga: jeśli umieścisz <table> w <jsp:include>, może być wielokrotnego użytku w innym miejscu w odpowiedzi innej niż 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>

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

Prawdopodobnie już zdajesz sobie sprawę, dlaczego XML jest tak dużypotężniejszy niż JSON, szczególnie w celu aktualizacji dokumentu HTML za pomocą Ajax. JSON jest zabawny, ale ogólnie przydatny tylko w przypadku tak zwanych „publicznych usług sieciowych”. Struktury MVC takie jak JSF używaj XML pod przykryciem do swojej magii ajax.

Ajaxifying istniejącego formularza

Możesz użyć jQuery $.serialize() aby łatwo zliczyć istniejące formularze POST bezbawiąc się przy zbieraniu i przekazywaniu poszczególnych parametrów wejściowych formularza. Przyjmując istniejącą formę, która działa idealnie bez JavaScript / jQuery (i tym samym łagodnie się psuje, gdy użytkownik ma wyłączoną obsługę 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>

Możesz go stopniowo ulepszać za pomocą ajax, jak poniżej:

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

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

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

W serwletu możesz rozróżnić zwykłe żądania i żądania ajax, jak poniżej:

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

The Wtyczka jQuery Form robi mniej więcej tak samo jak powyżej przykład jQuery, ale ma dodatkową przejrzystą obsługę multipart/form-data formularze wymagane przez przesyłanie plików.

Ręczne wysyłanie parametrów żądania do serwletu

Jeśli w ogóle nie masz formularza, a chciałeś po prostu wchodzić w interakcję z serwletem „w tle”, w którym chcesz zamieścić niektóre dane, możesz użyć jQuery $.param() aby łatwo przekonwertować obiekt JSON na ciąg zapytania zakodowany w adresie URL.

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

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

To samo doPost() Metoda pokazana powyżej może być ponownie użyta. Zauważ, że powyższa składnia również działa z $.get() w jQuery i doGet() w serwletu.

Ręczne wysyłanie obiektu JSON do serwletu

Jeśli jednak z jakiegoś powodu zamierzasz wysłać obiekt JSON jako całość, a nie jako indywidualne parametry żądania, musisz serializować go do ciągu za pomocą JSON.stringify() (nie jest częścią jQuery) i poinstruuj jQuery, aby ustawić typ zawartości żądania na application/json zamiast (domyślnie) application/x-www-form-urlencoded. Nie można tego zrobić za pośrednictwem $.post() funkcja wygody, ale należy to zrobić za pośrednictwem $.ajax() jak poniżej.

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

Zauważ, że wiele przystawek jest mieszanych contentType z dataType. The contentType reprezentuje typ żądanie ciało. The dataType reprezentuje (oczekiwany) typ odpowiedź ciało, co zwykle nie jest konieczne, ponieważ jQuery już je automatycznie wykrywa na podstawie odpowiedzi Content-Type nagłówek.

Następnie w celu przetworzenia obiektu JSON w plikuserwlet, który nie jest wysyłany jako pojedyncze parametry żądania, ale jako cały ciąg JSON w powyższy sposób, wystarczy ręcznie przeanalizować treść żądania za pomocą narzędzia JSON zamiast użycia getParameter() zwykły sposób. Mianowicie, serwlety nie obsługują application/json sformatowane żądania, ale tylko application/x-www-form-urlencoded lub multipart/form-data sformatowane wnioski. Gson obsługuje także parsowanie łańcucha JSON w obiekcie 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();
// ...

Pamiętaj, że to wszystko jest bardziej niezdarne niż zwykłe używanie $.param(). Zwykle chcesz użyć JSON.stringify() tylko jeśli usługa docelowa to np. usługa JAX-RS (RESTful), która z jakiegoś powodu jest w stanie zużywać tylko ciągi JSON, a nie zwykłe parametry żądania.

Wysyłanie przekierowania z serwletu

Ważne, aby zrozumieć i zrozumieć, że tak sendRedirect() i forward() wywołanie przez serwlet na żądanie ajax spowoduje tylko przekierowanie lub przekierowanie samo żądanie ajax a nie główny dokument / okno, z którego pochodzi żądanie ajax. JavaScript / jQuery w takim przypadku pobierałby tylko przekierowaną / przesłaną odpowiedź jako responseText zmienna w funkcji wywołania zwrotnego. Jeśli reprezentuje całą stronę HTML, a nie odpowiedź XML lub JSON specyficzną dla ajax, to wszystko, co możesz zrobić, to zastąpić go bieżącym dokumentem.

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

Pamiętaj, że to nie zmienia adresu URL jako użytkownika końcowegoznajduje się w pasku adresu przeglądarki. Występują zatem problemy z możliwością zaksięgowania. Dlatego o wiele lepiej jest po prostu zwrócić „instrukcję” dla JavaScript / jQuery, aby wykonać przekierowanie zamiast zwracać całą treść przekierowanej strony. Na przykład. zwracając wartość logiczną lub adres 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;
}

// ...
}

Zobacz też:


12 dla odpowiedzi nr 2

Właściwym sposobem na aktualizację strony aktualnie wyświetlanej w przeglądarce użytkownika (bez jej ponownego ładowania) jest wykonanie kodu w przeglądarce, który zaktualizuje DOM strony.

Ten kod to zazwyczaj javascriptosadzone lub połączone ze strony HTML, stąd sugestia AJAX. (W rzeczywistości, jeśli założymy, że zaktualizowany tekst pochodzi z serwera za pośrednictwem żądania HTTP, jest to klasyczny AJAX.)

Możliwe jest również wdrożenie tego rodzajucoś przy użyciu wtyczki lub dodatku do przeglądarki, choć wtyczka może mieć trudności z dostępem do struktur danych przeglądarki w celu zaktualizowania DOM. (Wtyczki kodu natywnego zwykle zapisują w ramce graficznej osadzonej na stronie).


10 dla odpowiedzi nr 3

Pokażę cały przykład serwletu i jak wywołać ajax.

Tutaj stworzymy prosty przykład, aby utworzyć formularz logowania za pomocą serwletu.

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>

Oto ajax Próbka

       $.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 dla odpowiedzi № 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 dla odpowiedzi № 5

Ajax (także AJAX) to skrót od AsynchronousJavaScript i XML) to grupa powiązanych ze sobą technik tworzenia stron internetowych wykorzystywanych po stronie klienta do tworzenia asynchronicznych aplikacji internetowych. Dzięki Ajax aplikacje internetowe mogą wysyłać dane i pobierać je z serwera asynchronicznie Poniżej znajduje się przykładowy kod:

Funkcja skryptu Java strony Jsp do przesyłania danych do serwletu z dwiema zmiennymi firstName i 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);

}

Serwlet do odczytu danych odsyła z powrotem do formatu jsp w formacie xml (możesz również użyć tekstu. Wystarczy zmienić treść odpowiedzi na tekst i renderować dane w funkcji 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 dla odpowiedzi № 6

Zwykle nie można zaktualizować strony z serwletu. Klient (przeglądarka) musi poprosić o aktualizację. Klient Eiter ładuje całą nową stronę lub żąda aktualizacji części istniejącej strony. Ta technika nazywa się Ajax.


3 dla odpowiedzi № 7

Za pomocą 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"
});}
}

W Servlet

request.getParameter("input")