Spring 3.0 中的 Ajax 简化

工程 | Keith Donald | 2010 年 1 月 25 日 | ...

在我的上一篇文章中,我向大家介绍了 Spring 3 在 Web 应用程序开发方面的几项增强功能。你们中的一些人表示对后续一篇关于 Ajax 远程调用的文章感兴趣。Spring 3 在这方面提供了很多可利用的东西。继续阅读,我将带你了解它。

Spring 和 Ajax 概述

在本文中,当我提到 Ajax 时,我指的是 Web 浏览器使用 JavaScript 与 Web 服务器进行异步通信的能力。在服务器端,Spring 提供了定义 Web 服务(包括 JavaScript 客户端使用的服务)的编程模型。在客户端,现在也没有人自己开发 Ajax 框架了。大多数人使用成熟的 JavaScript 框架,例如 jQueryDojo

对 Ajax 客户端的支持

在版本 3 之前,Spring 没有提供对 Ajax 远程调用的支持。但这并没有阻止我们的用户扩展 Spring 来实现它,或者自己集成其他选项。有些人使用 DWR,尤其是在 JavaScript 框架兴起之前的时期。最近,以 JSON 作为数据交换格式的 REST 式远程调用变得更加流行,尤其因为 jQuery 等库使其变得非常容易实现

随着 Spring 3 的发布,Spring MVC 模块中正式提供了对使用 JSON 进行 Ajax 远程调用的支持。这包括使用 Spring MVC 的 @Controller 编程模型生成 JSON 响应和绑定 JSON 请求的支持。在本文中,我将重点介绍如何使用这一支持来实现几个 Ajax 用例。就像我上一篇文章一样,我将通过一个你可以自己实验的示例应用程序来引导你完成。

MVC Ajax 示例

mvc-ajax 项目旨在演示 Spring MVC 对 JSON 的支持。该项目可在我们的 spring-samples Subversion 仓库中找到,可以使用 Maven 构建,并可导入 STS / Eclipse。mvc-ajax 与我在上一篇文章中介绍的 mvc-basic 项目结构相同。实际上,两者的 Spring 配置是完全一样的。

首先将项目部署到你的 Servlet 容器,然后访问 localhost:8080/mvc-ajax 的欢迎页面。由于我使用 STS,我先将项目导入 IDE,然后将其部署到内置的 Tomcat / tc-server 实例。

从服务器获取 JSON

在欢迎页面,点击“Ajax @Controller 示例”链接。你将看到一个创建新 Account 的表单。当你离开“名称”字段时,浏览器会询问服务器你刚刚输入的名称是否可用。如果不可用,将显示错误消息,并且表单将保持禁用状态,直到你输入一个可用的名称。处理此功能的客户端 JavaScript 位于 /WEB-INF/views/account/createForm.jsp 中,代码如下:


$(document).ready(function() {
    // check name availability on focus lost
    $('#name').blur(function() {
        checkAvailability();
    });
});

function checkAvailability() {
    $.getJSON("account/availability", { name: $('#name').val() }, function(availability) {
        if (availability.available) {
            fieldValidated("name", { valid : true });
        } else {
            fieldValidated("name", { valid : false,
                message : $('#name').val() + " is not available, try " + availability.suggestions });
        }
    });
}

这里没有什么 Spring 特定的内容,只是标准的 jQuery JavaScript。

在服务器端,负责 account/availability 资源的 Controller 是标准的 Java 类,带有一些 Spring MVC 注解:


@RequestMapping(value="/availability", method=RequestMethod.GET)
public @ResponseBody AvailabilityStatus getAvailability(@RequestParam String name) {
    for (Account a : accounts.values()) {
        if (a.getName().equals(name)) {
            return AvailabilityStatus.notAvailable(name);
        }
    }
    return AvailabilityStatus.available();
}

AvailabilityStatus 是一个普通的 Java 值对象,具有两个属性:一个可用性标志,告诉客户端用户名是否可用;以及一个替代名称数组,如果所需的名称不可用则建议使用。@ResponseBody 注解指示 Spring MVC 将 AvailabilityStatus 序列化到客户端。Spring MVC 自动将其序列化为 JSON,因为客户端接受该内容类型。

在底层,Spring MVC 将序列化任务委托给 HttpMessageConverter。在这种情况下,Spring MVC 调用基于 Jackson JSON 处理器的 MappingJacksonHttpMessageConverter。当你使用 mvc:annotation-driven 配置元素且 classpath 中包含 Jackson 时,此实现会自动启用。

很酷吧?尝试创建一个 Account,然后用相同的名称再创建一个。你应该会看到一个错误消息,建议使用其他名称。打开 Firefox 的 Firebug 或 Safari 的 Web Inspector 来调试异步交互。

向服务器 POST JSON

Spring MVC 也提供了向服务器发送 JSON 的支持。我发现这种需求不太常见,因为通常 POST 表单参数就足够了。然而,JSON 提供了一种灵活的数据交换格式,功能更丰富的 JavaScript 客户端可以方便地使用。在这些情况下,能够将 JSON 映射到服务器端 Java 对象进行处理是一个有用的功能。

在示例中,一个 JavaScript 事件处理器拦截了表单提交事件,并将表单数据作为 JSON POST 到服务器。服务器返回新创建 Account 的 ID,然后用于显示一个模态确认对话框:


$("#account").submit(function() {
    var account = $(this).serializeObject();
    $.postJSON("account", account, function(data) {
        $("#assignedId").val(data.id);
        showPopup();
    });
    return false;
});

在服务器端,Controller 也是带有 Spring MVC 注解的标准 Java 类:


@RequestMapping(method=RequestMethod.POST)
public @ResponseBody Map<String, ? extends Object> create(@RequestBody Account account, HttpServletResponse response) {
    Set<ConstraintViolation<Account>> failures = validator.validate(account);
    if (!failures.isEmpty()) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        return validationMessages(failures);
    } else {
        accounts.put(account.assignId(), account);
        return Collections.singletonMap("id", account.getId());
    }
}

在这里,@RequestBody 注解指示 Spring MVC 将 HTTP 请求体映射到 Account 对象。Spring MVC 知道从 JSON 映射,因为客户端将请求的 Content Type 设置为 application/json。

create 方法还验证了 Account 对象。如果存在验证错误,将返回 HTTP 400 并带上错误消息;否则,将返回 HTTP 200 并带上分配的账户 ID。

总结

Spring 3 作为 Spring MVC 模块的一部分,提供了对使用 JSON 的一流 Ajax 支持。这包括结合 Jackson JSON 处理器,使用 Spring MVC 的 @Controller 编程模型生成 JSON 响应和绑定 JSON 请求的支持。在本文中,我向大家展示了这项支持是如何工作的。我希望这篇文章对你有所帮助,并期待听到更多你在自己应用程序中使用 Spring 3 的经验!

获取 Spring 快讯

通过 Spring 快讯保持联系

订阅

保持领先

VMware 提供培训和认证,助你加速进步。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

近期活动

查看 Spring 社区的所有近期活动。

查看全部