Jak korzystać z Servletów i Ajax?

Jestem nowy w Web apps i Servletach i mam następujące pytanie:

Za każdym razem, gdy drukuję coś wewnątrz servletu i wywołuję go przez przeglądarkę, zwraca nową stronę zawierającą ten tekst. Czy istnieje sposób na wydrukowanie tekstu na bieżącej stronie za pomocą Ajax?

Author: Taryn, 2010-11-06

7 answers

W rzeczywistości słowo kluczowe to "ajax": asynchroniczny JavaScript i XML. Jednak w ostatnich latach jest to więcej niż często asynchroniczny JavaScript i JSON. Zasadniczo pozwalasz JS wykonywać asynchroniczne żądanie HTTP i aktualizować drzewo HTML DOM na podstawie danych odpowiedzi.

Ponieważ jest to dość żmudna praca , 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 obejmuje jak najwięcej błędów / dziwactw specyficznych dla przeglądarki, takich jak jQuery, Prototype, Mootools . Ponieważ jQuery jest obecnie najbardziej popularny, użyję go w poniższych przykładach.

Przykład zwracający String jako zwykły tekst

Utwórz /some.jsp jak poniżej (uwaga: kod nie oczekuje, że plik JSP zostanie umieszczony w podfolderze, jeśli to zrobisz, odpowiednio zmień adres URL serwleta):

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

Create a servlet z metodą doGet(), która wygląda tak:

@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 servlet na wzorze URL /someservlet lub /someservlet/* Jak Poniżej (oczywiście wzór URL jest wolny do wyboru, ale musisz odpowiednio zmienić adres URL someservlet w przykładach kodu JS): {]}

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

Lub, gdy nie jesteś jeszcze na kontenerze zgodnym z Servletem 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc lub nowszym), zmapuj go w web.xml w staromodny sposób (Zobacz także nasza Wiki serwletów strona):

<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ź servleta.

Return List<String> jako JSON

Z JSON zamiast zwykłego tekstu jako formatu odpowiedzi możesz nawet zrobić kilka kroków dalej. Pozwala to na większą dynamikę. Po pierwsze, chcesz mieć narzędzie do konwersji między obiektami Java i ciągami JSON. Jest mnóstwo ich również (Zobacz na dole tej strony dla przeglądu). Moim ulubionym jest Google Gson . Pobierz i umieść jego plik JAR w folderze /WEB-INF/lib aplikacji internetowej.

Oto przykład, który wyświetla List<String> jako <ul><li>. 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);
}

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 przetwarza odpowiedź jako JSON i daje bezpośrednio obiekt JSON (responseJson) jako argument funkcji, gdy ustawisz typ zawartości odpowiedzi na application/json. Jeśli zapomnisz go ustawić lub polegasz na domyślnej wartości text/plain lub text/html, argument responseJson nie da Ci obiektu JSON, ale zwykły ciąg waniliowy i będziesz musiał ręcznie bawić się z JSON.parse() następnie, co jest całkowicie niepotrzebne, jeśli ustawisz typ treści na pierwszym miejscu.

Return Map<String, String> jako JSON

Oto kolejny przykład, który wyświetla Map<String, String> jako <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>

Return List<Entity> jako JSON

Oto przykład, który wyświetla List<Product> w <table> gdzie Klasa Product ma właściwości Long id, String name i BigDecimal price. 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);
}

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

Zwracanie List<Entity> jako XML

Oto przykład, który robi to samo co poprzedni przykład, ale potem z XML zamiast JSON. Podczas używania JSP jako generatora wyjściowego XML zobaczysz, że kodowanie tabeli i w ogóle jest mniej żmudne. JSTL jest w ten sposób jest to o wiele bardziej pomocne, ponieważ można go używać do iteracji wyników i formatowania danych po stronie serwera. 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);
}
W przeciwieństwie do Ajaksa, nie można go używać w żadnej innej formie.]}
<?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ż zdasz sobie sprawę, dlaczego XML jest o wiele bardziej wydajny niż JSON w konkretnym celu aktualizacji dokumentu HTML za pomocą Ajax. JSON jest śmieszny, ale przecież ogólnie użyteczny tylko dla tzw. "publicznych serwisów internetowych". Frameworki MVC, takie jak JSF , używają XML pod okładkami dla swojej magii ajax.

Ajaksowanie istniejącej formy

Możesz użyć jQuery $.serialize() aby łatwo ajaxify istniejących formularzy POST bez majstrowania z zbierania i przekazywania poszczególnych parametrów wejściowych formularza. Przyjmując istniejącą formę, która działa doskonale bez JavaScript / jQuery (a tym samym rozkłada się wdzięcznie, gdy enduser ma JavaScript disabled):

<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 stopniowo ulepszać go 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.
});

Można w servletie 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.
    }
}

Wtyczka jQuery Form robi mniej lub bardziej to samo, co powyższy przykład jQuery, ale ma dodatkową przezroczystą obsługę formularzy multipart/form-data zgodnie z wymaganiami przesyłania plików.

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

Jeśli nie masz formularza w ogóle, ale po prostu chciał wejść w interakcję z serwletem "w tle", w którym chcesz opublikować jakieś dane, a następnie możesz użyć jQuery $.param() aby łatwo przekonwertować obiekt JSON na zakodowany URL ciąg zapytania.

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

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

Ta sama metoda doPost(), Jak pokazano powyżej, może być ponownie wykorzystana. Zauważ, że powyższa składnia działa również z $.get() w jQuery i doGet() w servlet.

Ręczne wysyłanie obiektu JSON do servleta

Jeśli jednak zamierzasz wysłać obiekt JSON jako whole zamiast jako indywidualne parametry żądania z jakiegoś powodu, wtedy trzeba by serializować go do Ciągu za pomocą JSON.stringify() (nie jest częścią jQuery) i poinstruować jQuery, aby ustawił typ zawartości żądania na application/json zamiast (domyślnie) application/x-www-form-urlencoded. Nie można tego zrobić za pomocą funkcji wygody $.post(), ale należy to zrobić za pomocą $.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) {
        // ...
    }
});

Należy pamiętać, że wiele przystawek mieszać contentType z dataType. contentType reprezentuje typ ciała żądania . dataType reprezentuje (oczekiwany) typ ciała response, który jest zwykle niepotrzebny, ponieważ jQuery już automatycznie wykrywa go na podstawie nagłówka Content-Type odpowiedzi.

Następnie, aby przetworzyć obiekt JSON w serwlecie, który nie jest wysyłany jako indywidualne parametry żądania, ale jako cały łańcuch JSON w powyższy sposób, wystarczy ręcznie przetworzyć treść żądania za pomocą narzędzia JSON zamiast za pomocą getParameter() w zwykły sposób. Mianowicie, servlety nie obsługują formatowanych żądań application/json, ale tylko application/x-www-form-urlencoded lub multipart/form-data sformatowane żądania. Gson obsługuje również parsowanie łańcucha JSON do obiektu 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();
// ...

Należy pamiętać, że to wszystko jest bardziej niezdarne niż tylko za pomocą $.param(). Normalnie, chcesz używać JSON.stringify() tylko wtedy, gdy usługą docelową jest np. usługa JAX-RS (RESTful), która z jakiegoś powodu jest w stanie tylko zużywać ciągi JSON, a nie regularne parametry żądania.

Wysyłanie przekierowania z servleta

Ważne jest, aby zdać sobie sprawę i zrozumieć, że każdy]} w przeciwieństwie do innych serwletów, serwlet nie może być używany do wysyłania żądań ajax, a jedynie do przekazywania lub przekierowywania żądań ajax, a nie do głównego dokumentu/okna, z którego pochodzi żądanie ajax. JavaScript / jQuery w takim przypadku pobierze tylko przekierowaną / przekazaną odpowiedź jako zmienną responseText 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ć nim bieżący dokument.
document.open();
document.write(responseText);
document.close();

Zauważ, że to nie zmienia adresu URL, który użytkownik końcowy widzi na pasku adresu przeglądarki. Więc są problemy z bookmarkability. Dlatego o wiele lepiej jest po prostu zwrócić "instrukcję" dla JavaScript/jQuery, aby wykonać przekierowanie, zamiast zwracać całą zawartość przekierowanej strony. Np. 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ż:

 510
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:18

Właściwym sposobem aktualizacji strony aktualnie wyświetlanej w przeglądarce Użytkownika (bez jej przeładowywania) jest wykonanie jakiegoś kodu w przeglądarce aktualizującego DOM strony.

Ten kod jest zazwyczaj javascript, który jest osadzony lub linkowany 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ż zaimplementowanie tego typu rzeczy za pomocą jakiejś wtyczki do przeglądarki lub dodatek, choć może to być trudne dla wtyczki, aby dotrzeć do struktur danych przeglądarki, aby zaktualizować DOM. (Wtyczki kodu natywnego Zwykle zapisują do jakiejś ramki graficznej osadzonej na stronie.)

 13
Author: Stephen C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-16 22:40:36

Pokażę Ci cały przykład servlet & jak wywołać ajax.

Tutaj stworzymy prosty przykład tworzenia formularza logowania przy użyciu servletu.

Indeks.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 przykład 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
Author: Mitul Maheshwari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-09 09:11:57

Ajax (także AJAX) - grupa powiązanych ze sobą technik tworzenia stron internetowych używanych po stronie klienta do tworzenia asynchronicznych aplikacji internetowych. Dzięki Ajax aplikacje internetowe mogą asynchronicznie wysyłać dane do serwera i pobierać je z niego Poniżej przykładowy kod:

Strona Jsp funkcja java script do przesyłania danych do servletu z dwoma 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);

    }

Servlet do odczytu danych wysyłanych z powrotem do jsp w formacie xml (Ty przydałby się też tekst. 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>");
}
 6
Author: user3468976,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 22:09:12

Normalnie nie można zaktualizować strony z serwletu. Klient (przeglądarka) musi zażądać aktualizacji. Klient Eiter ładuje całą nową stronę lub żąda aktualizacji do części istniejącej strony. Technika ta nazywa się Ajax.

 4
Author: Peter Knego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-06 10:30:37

Używanie 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")
 3
Author: Thakhani Tharage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-03 11:04:14