如何使用Servlet和Ajax?

如何使用Servlet和Ajax?,第1张

如何使用Servlet和Ajax?

实际上,关键字是“ ajax”: 异步Javascript和XML 。但是,去年,它比 异步Javascript和JSON
更为常见。基本上,让JS执行异步HTTP请求并根据响应数据更新HTML DOM树。

由于使其能够在所有浏览器(尤其是Internet
Explorer与其他浏览器)上进行是一项繁琐的工作,因此有大量的Javascript库简化了单个功能,并涵盖了尽可能多的特定于浏览器的错误/怪癖。
,例如jQuery,Prototype和Mootools。由于jQuery最近最流行,因此我将在以下示例中使用它。

String
以纯文本形式返回的启动示例

创建

/some.jsp
如下所示(注意:代码不希望将JSP文件放在子文件夹中,如果这样做,请相应地更改servlet URL):

<!DOCTYPE html><html lang="en">    <head>        <title>SO question 4112686</title>        <script src="http://pre.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>

使用如下

doGet()
方法创建一个servlet :

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

将此servlet映射到

/someservlet
/someservlet/*
如下的URL模式上(显然,URL模式是您自由选择的,但是您需要相应地
someservlet
在所有地方更改JS代码示例中的URL):

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

或者,如果您还没有使用与Servlet 3.0兼容的容器(Tomcat 7,Glassfish 3,JBoss AS
6等,或更新的容器),请以

web.xml
老式的方式进行映射:

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

现在,在浏览器中打开http:// localhost:8080 / context /
test.jsp并按按钮。您将看到div的内容随servlet响应一起更新。

List<String>
作为JSON 返回

使用JSON而不是纯文本作为响应格式,您甚至可以进一步采取一些措施。它允许更多的动态。首先,您想要一个工具来在Java对象和JSON字符串之间进行转换。也有很多(请参见本页底部的概述)。我个人最喜欢的是Google
Gson。下载其JAR文件并将其放在

/WEB-INF/lib
Web应用程序的文件夹中。

这是显示

List<String>
为的示例
<ul><li>
。Servlet:

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

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

请注意,

responseJson
当您将响应内容类型设置为时,jQuery会自动将响应解析为JSON,并直接为您提供JSON对象()作为函数参数
application/json
。如果您忘记设置它或依赖于默认值
text/plain
or
text/html
,那么该
responseJson
参数将不会为您提供JSON对象,而是一个普通的香草字符串,并且您之后需要手动进行 *** 作[
JSON.parse()
],因此,如果您完全不需要首先设置内容类型。

Map<String, String>
作为JSON 返回

这是另一个显示

Map<String, String>
为的示例
<option>

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

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

<select id="someselect"></select>
List<Entity>
作为JSON 返回

下面是其中显示了一个例子

List<Product>
<table>
,其中
Product
类具有的属性
Long id
Stringname
BigDecimal price
。Servlet:

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

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>.        });    });});
List<Entity>
以XML形式返回

这是一个与上一个示例有效地相同的示例,但是使用XML而不是JSON。当使用JSP作为XML输出生成器时,您会发现对表和所有代码进行编码都比较麻烦。JSTL更加有用,因为您可以实际使用它来遍历结果并执行服务器端数据格式化。Servlet:

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

JSP代码(请注意:如果将放在

<table>
<jsp:include>
,它可以在非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>

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

您现在可能已经意识到为什么出于使用Ajax更新HTML文档的特定目的,XML比JSON强大得多。JSON很有趣,但毕竟通常只对所谓的“公共Web服务”有用。像JSF这样的MVC框架在其ajax魔术的幕后使用XML。

合并现有表格

您可以使用jQuery

$.serialize()
轻松地将现有的POST表单废除,而无需费心收集和传递各个表单输入参数。假设现有形式在没有Javascript
/ jQuery的情况下也能很好地工作(因此,当最终用户禁用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>

您可以使用ajax逐步增强它,如下所示:

$(document).on("submit", "#someform", function(event) {    var $form = $(this);    $.post($form.attr("action"), $form.serialize(), function(response) {        // ...    });    event.preventDefault(); // important! Prevents submitting the form.});

您可以在servlet中区分普通请求和ajax请求,如下所示:

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

的jQuery的表格插件确实更少或更多的与上述相同的jQuery例子,但它具有用于附加透明支持

multipart/form-data
所要求的文件上传形式。

手动将请求参数发送到servlet

如果您根本没有表单,而只想与“后台”与servlet交互,从而希望发布一些数据,那么您可以使用jQuery

$.param()
轻松地将JSON对象转换为URL编码请求参数。

var params = {    foo: "fooValue",    bar: "barValue",    baz: "bazValue"};$.post("someservlet", $.param(params), function(response) {    // ...});

doPost()
可以重复使用上面显示的相同方法。请注意,以上语法
$.get()
在jQuery和
doGet()
servlet中也适用。

手动将JSON对象发送到servlet

不过,若你打算发送JSON对象作为一个整体,而不是作为单独的请求参数出于某种原因,那么你就需要使用到它序列化到一个字符串

JSON.stringify()
(不是jQuery的部分),并指示jQuery来设置请求的内容类型
application/json
,而不是的(默认值)
application/x-www-form-urlenpred
。这无法通过
$.post()
便捷功能完成,但需要通过
$.ajax()
以下方式完成。

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

请注意,许多启动器

contentType
与混合使用
dataType
。该
contentType
表示的类型 请求
体。的
dataType
表示(预期)类型的 反应 体,这通常是不必要的,因为已经jQuery的自动检测它基于响应的
Content-Type
报头中。

然后,为了以上述方式处理不是作为单独的请求参数而是作为整个JSON字符串发送的Servlet中的JSON对象,您只需要使用JSON工具手动解析请求主体,而无需使用

getParameter()
通常的道路。也就是说,小服务程序不支持
application/json
格式的请求,但只有
application/x-www-form-urlenpred
multipart/form-data
格式的请求。Gson还支持将JSON字符串解析为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();// ...

请注意,这不仅仅是使用

$.param()
。通常,
JSON.stringify()
仅当目标服务是例如JAX-
RS(RESTful)服务时才使用,由于某种原因,该服务仅能够使用JSON字符串,而不能使用常规请求参数。

从Servlet发送重定向

认识和理解的重要之处在于,servlet对ajax请求的任何

sendRedirect()
forward()
调用只会转发或重定向
ajax请求本身 ,而不转发或重定向 ajax请求产生 的主文档/窗口。在这种情况下,Javascript /
jQuery仅
responseText
在回调函数中将重定向/转发的响应作为变量检索。如果它代表整个HTML页面,而不是特定于Ajax的XML或JSON响应,那么您所能做的就是用它替换当前文档。

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

请注意,这不会像最终用户在浏览器的地址栏中看到的那样更改URL。因此,书签性存在问题。因此,最好为Javascript /jQuery返回一个“指令”以执行重定向,而不是返回已重定向页面的全部内容。例如,通过返回布尔值或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;    }    // ...}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5066280.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存