Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Indeed, the keyword is "ajax": <em>Asynchronous JavaScript and XML</em>. However, last years it's more than often <em>Asynchronous JavaScript and JSON</em>. Basically, you let JS execute an asynchronous HTTP request and update the HTML DOM tree based on the response data.</p> <p>Since it's pretty a <a href="https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started" rel="noreferrer">tedious</a> work to make it to work across all browsers (especially Internet Explorer versus others), there are plenty of JavaScript libraries out which simplifies this in single functions and covers as many as possible browser-specific bugs/quirks under the hoods, such as <a href="http://jquery.com" rel="noreferrer">jQuery</a>, <a href="http://www.prototypejs.org/" rel="noreferrer">Prototype</a>, <a href="http://mootools.net/" rel="noreferrer">Mootools</a>. Since jQuery is most popular these days, I'll use it in the below examples.</p> <h1>Kickoff example returning <code>String</code> as plain text</h1> <p>Create a <code>/some.jsp</code> like below (note: the code doesn't expect the JSP file being placed in a subfolder, if you do so, alter servlet URL accordingly):</p> <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;title&gt;SO question 4112686&lt;/title&gt; &lt;script src="http://code.jquery.com/jquery-latest.min.js"&gt;&lt;/script&gt; &lt;script&gt; $(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. }); }); &lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;button id="somebutton"&gt;press here&lt;/button&gt; &lt;div id="somediv"&gt;&lt;/div&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>Create a servlet with a <code>doGet()</code> method which look like this:</p> <pre class="lang-java prettyprint-override"><code>@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. } </code></pre> <p>Map this servlet on an URL pattern of <code>/someservlet</code> or <code>/someservlet/*</code> as below (obviously, the URL pattern is free to your choice, but you'd need to alter the <code>someservlet</code> URL in JS code examples over all place accordingly):</p> <pre class="lang-java prettyprint-override"><code>@WebServlet("/someservlet/*") public class SomeServlet extends HttpServlet { // ... } </code></pre> <p>Or, when you're not on a Servlet 3.0 compatible container yet (Tomcat 7, Glassfish 3, JBoss AS 6, etc or newer), then map it in <code>web.xml</code> the old fashioned way (see also <a href="https://stackoverflow.com/tags/servlets/info">our Servlets wiki page</a>):</p> <pre class="lang-xml prettyprint-override"><code>&lt;servlet&gt; &lt;servlet-name&gt;someservlet&lt;/servlet-name&gt; &lt;servlet-class&gt;com.example.SomeServlet&lt;/servlet-class&gt; &lt;/servlet&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;someservlet&lt;/servlet-name&gt; &lt;url-pattern&gt;/someservlet/*&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; </code></pre> <p>Now open the <a href="http://localhost:8080/context/test.jsp" rel="noreferrer">http://localhost:8080/context/test.jsp</a> in the browser and press the button. You'll see that the content of the div get updated with the servlet response.</p> <h1>Returning <code>List&lt;String&gt;</code> as JSON</h1> <p>With <a href="http://www.hunlock.com/blogs/Mastering_JSON_%28_JavaScript_Object_Notation_%29" rel="noreferrer">JSON</a> instead of plaintext as response format you can even get some steps further. It allows for more dynamics. First, you'd like to have a tool to convert between Java objects and JSON strings. There are plenty of them as well (see the bottom of <a href="http://json.org/" rel="noreferrer">this page</a> for an overview). My personal favourite is <a href="http://code.google.com/p/google-gson/" rel="noreferrer">Google Gson</a>. Download and put its JAR file in <code>/WEB-INF/lib</code> folder of your webapplication. </p> <p>Here's an example which displays <code>List&lt;String&gt;</code> as <code>&lt;ul&gt;&lt;li&gt;</code>. The servlet:</p> <pre class="lang-java prettyprint-override"><code>@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List&lt;String&gt; list = new ArrayList&lt;&gt;(); 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); } </code></pre> <p>The JS code:</p> <pre class="lang-js prettyprint-override"><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 = $("&lt;ul&gt;").appendTo($("#somediv")); // Create HTML &lt;ul&gt; element and append it to HTML DOM element with ID "somediv". $.each(responseJson, function(index, item) { // Iterate over the JSON array. $("&lt;li&gt;").text(item).appendTo($ul); // Create HTML &lt;li&gt; element, set its text content with currently iterated item and append it to the &lt;ul&gt;. }); }); }); </code></pre> <p>Do note that jQuery automatically parses the response as JSON and gives you directly a JSON object (<code>responseJson</code>) as function argument when you set the response content type to <code>application/json</code>. If you forget to set it or rely on a default of <code>text/plain</code> or <code>text/html</code>, then the <code>responseJson</code> argument wouldn't give you a JSON object, but a plain vanilla string and you'd need to manually fiddle around with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" rel="noreferrer"><code>JSON.parse()</code></a> afterwards, which is thus totally unnecessary if you set the content type right in first place.</p> <h1>Returning <code>Map&lt;String, String&gt;</code> as JSON</h1> <p>Here's another example which displays <code>Map&lt;String, String&gt;</code> as <code>&lt;option&gt;</code>:</p> <pre class="lang-java prettyprint-override"><code>@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map&lt;String, String&gt; options = new LinkedHashMap&lt;&gt;(); 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); } </code></pre> <p>And the JSP:</p> <pre class="lang-js prettyprint-override"><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 $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. $("&lt;option&gt;").val(key).text(value).appendTo($select); // Create HTML &lt;option&gt; element, set its value with currently iterated key and its text content with currently iterated item and finally append it to the &lt;select&gt;. }); }); }); </code></pre> <p>with </p> <pre class="lang-html prettyprint-override"><code>&lt;select id="someselect"&gt;&lt;/select&gt; </code></pre> <h1>Returning <code>List&lt;Entity&gt;</code> as JSON</h1> <p>Here's an example which displays <code>List&lt;Product&gt;</code> in a <code>&lt;table&gt;</code> where the <code>Product</code> class has the properties <code>Long id</code>, <code>String name</code> and <code>BigDecimal price</code>. The servlet:</p> <pre class="lang-java prettyprint-override"><code>@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List&lt;Product&gt; products = someProductService.list(); String json = new Gson().toJson(products); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); } </code></pre> <p>The JS code:</p> <pre class="lang-js prettyprint-override"><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 = $("&lt;table&gt;").appendTo($("#somediv")); // Create HTML &lt;table&gt; element and append it to HTML DOM element with ID "somediv". $.each(responseJson, function(index, product) { // Iterate over the JSON array. $("&lt;tr&gt;").appendTo($table) // Create HTML &lt;tr&gt; element, set its text content with currently iterated item and append it to the &lt;table&gt;. .append($("&lt;td&gt;").text(product.id)) // Create HTML &lt;td&gt; element, set its text content with id of currently iterated product and append it to the &lt;tr&gt;. .append($("&lt;td&gt;").text(product.name)) // Create HTML &lt;td&gt; element, set its text content with name of currently iterated product and append it to the &lt;tr&gt;. .append($("&lt;td&gt;").text(product.price)); // Create HTML &lt;td&gt; element, set its text content with price of currently iterated product and append it to the &lt;tr&gt;. }); }); }); </code></pre> <h1>Returning <code>List&lt;Entity&gt;</code> as XML</h1> <p>Here's an example which does effectively the same as previous example, but then with XML instead of JSON. When using JSP as XML output generator you'll see that it's less tedious to code the table and all. JSTL is this way much more helpful as you can actually use it to iterate over the results and perform server side data formatting. The servlet:</p> <pre class="lang-java prettyprint-override"><code>@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List&lt;Product&gt; products = someProductService.list(); request.setAttribute("products", products); request.getRequestDispatcher("/WEB-INF/xml/products.jsp").forward(request, response); } </code></pre> <p>The JSP code (note: if you put the <code>&lt;table&gt;</code> in a <code>&lt;jsp:include&gt;</code>, it may be reusable elsewhere in a non-ajax response):</p> <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;%@page contentType="application/xml" pageEncoding="UTF-8"%&gt; &lt;%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt; &lt;%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %&gt; &lt;data&gt; &lt;table&gt; &lt;c:forEach items="${products}" var="product"&gt; &lt;tr&gt; &lt;td&gt;${product.id}&lt;/td&gt; &lt;td&gt;&lt;c:out value="${product.name}" /&gt;&lt;/td&gt; &lt;td&gt;&lt;fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/c:forEach&gt; &lt;/table&gt; &lt;/data&gt; </code></pre> <p>The JS code:</p> <pre class="lang-js prettyprint-override"><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 &lt;data&gt; element and append its HTML to HTML DOM element with ID "somediv". }); }); </code></pre> <p>You'll by now probably realize why XML is so much more powerful than JSON for the particular purpose of updating a HTML document using Ajax. JSON is funny, but after all generally only useful for so-called "public web services". MVC frameworks like <a href="https://stackoverflow.com/tags/jsf/info">JSF</a> use XML under the covers for their ajax magic.</p> <h1>Ajaxifying an existing form</h1> <p>You can use jQuery <a href="https://api.jquery.com/serialize/" rel="noreferrer"><code>$.serialize()</code></a> to easily ajaxify existing POST forms without fiddling around with collecting and passing the individual form input parameters. Assuming an existing form which works perfectly fine without JavaScript/jQuery (and thus degrades gracefully when enduser has JavaScript disabled):</p> <pre class="lang-html prettyprint-override"><code>&lt;form id="someform" action="someservlet" method="post"&gt; &lt;input type="text" name="foo" /&gt; &lt;input type="text" name="bar" /&gt; &lt;input type="text" name="baz" /&gt; &lt;input type="submit" name="submit" value="Submit" /&gt; &lt;/form&gt; </code></pre> <p>You can progressively enhance it with ajax as below:</p> <pre class="lang-js prettyprint-override"><code>$(document).on("submit", "#someform", function(event) { var $form = $(this); $.post($form.attr("action"), $form.serialize(), function(response) { // ... }); event.preventDefault(); // Important! Prevents submitting the form. }); </code></pre> <p>You can in the servlet distinguish between normal requests and ajax requests as below:</p> <pre class="lang-java prettyprint-override"><code>@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. } } </code></pre> <p>The <a href="http://malsup.com/jquery/form/" rel="noreferrer">jQuery Form plugin</a> does less or more the same as above jQuery example, but it has additional transparent support for <code>multipart/form-data</code> forms as required by file uploads.</p> <h1>Manually sending request parameters to servlet</h1> <p>If you don't have a form at all, but just wanted to interact with the servlet "in the background" whereby you'd like to POST some data, then you can use jQuery <a href="http://api.jquery.com/jquery.param/" rel="noreferrer"><code>$.param()</code></a> to easily convert a JSON object to an URL-encoded query string.</p> <pre class="lang-js prettyprint-override"><code>var params = { foo: "fooValue", bar: "barValue", baz: "bazValue" }; $.post("someservlet", $.param(params), function(response) { // ... }); </code></pre> <p>The same <code>doPost()</code> method as shown here above can be reused. Do note that above syntax also works with <code>$.get()</code> in jQuery and <code>doGet()</code> in servlet.</p> <h1>Manually sending JSON object to servlet</h1> <p>If you however intend to send the JSON object as a whole instead of as individual request parameters for some reason, then you'd need to serialize it to a string using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify" rel="noreferrer"><code>JSON.stringify()</code></a> (not part of jQuery) and instruct jQuery to set request content type to <code>application/json</code> instead of (default) <code>application/x-www-form-urlencoded</code>. This can't be done via <code>$.post()</code> convenience function, but needs to be done via <code>$.ajax()</code> as below.</p> <pre class="lang-js prettyprint-override"><code>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) { // ... } }); </code></pre> <p>Do note that a lot of starters mix <code>contentType</code> with <code>dataType</code>. The <code>contentType</code> represents the type of the <strong>request</strong> body. The <code>dataType</code> represents the (expected) type of the <strong>response</strong> body, which is usually unnecessary as jQuery already autodetects it based on response's <code>Content-Type</code> header.</p> <p>Then, in order to process the JSON object in the servlet which isn't being sent as individual request parameters but as a whole JSON string the above way, you only need to manually parse the request body using a JSON tool instead of using <code>getParameter()</code> the usual way. Namely, servlets don't support <code>application/json</code> formatted requests, but only <code>application/x-www-form-urlencoded</code> or <code>multipart/form-data</code> formatted requests. Gson also supports parsing a JSON string into a JSON object.</p> <pre class="lang-java prettyprint-override"><code>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(); // ... </code></pre> <p>Do note that this all is more clumsy than just using <code>$.param()</code>. Normally, you want to use <code>JSON.stringify()</code> only if the target service is e.g. a JAX-RS (RESTful) service which is for some reason only capable of consuming JSON strings and not regular request parameters.</p> <h1>Sending a redirect from servlet</h1> <p>Important to realize and understand is that any <code>sendRedirect()</code> and <code>forward()</code> call by the servlet on an ajax request would only forward or redirect <em>the ajax request itself</em> and not the main document/window where the ajax request originated. JavaScript/jQuery would in such case only retrieve the redirected/forwarded response as <code>responseText</code> variable in the callback function. If it represents a whole HTML page and not an ajax-specific XML or JSON response, then all you could do is to replace the current document with it.</p> <pre><code>document.open(); document.write(responseText); document.close(); </code></pre> <p>Note that this doesn't change the URL as enduser sees in browser's address bar. So there are issues with bookmarkability. Therefore, it's much better to just return an "instruction" for JavaScript/jQuery to perform a redirect instead of returning the whole content of the redirected page. E.g. by returning a boolean, or an URL.</p> <pre><code>String redirectURL = "http://example.com"; Map&lt;String, String&gt; data = new HashMap&lt;&gt;(); data.put("redirect", redirectURL); String json = new Gson().toJson(data); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); </code></pre> <p></p> <pre><code>function(responseJson) { if (responseJson.redirect) { window.location = responseJson.redirect; return; } // ... } </code></pre> <h3>See also:</h3> <ul> <li><a href="https://stackoverflow.com/questions/2132242/need-to-call-servlet-from-javascript-along-with-parameters">Call Servlet and invoke Java code from JavaScript along with parameters</a></li> <li><a href="https://stackoverflow.com/questions/3832792/access-java-servlet-jsp-jstl-el-variables-in-javascript">Access Java / Servlet / JSP / JSTL / EL variables in JavaScript</a></li> <li><a href="https://stackoverflow.com/questions/2600582/how-to-switch-easily-between-ajax-based-website-and-basic-html-website/">How to switch easily between ajax-based website and basic HTML website?</a></li> <li><a href="https://stackoverflow.com/questions/6914152/how-to-upload-files-to-server-using-jsp-servlet-and-ajax">How to upload files to server using JSP/Servlet and Ajax?</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload