第 14 章 JSON 数据交互和 RESTful 支持

Spring MVC 在数据绑定的过程中,需要对传递数据的格式和类型进行转换,它既可以转换 String 类型的数据,也能够转换 JSON 等其他类型的数据。 通过前面章节学习,大家已经掌握 String 等数据类型的转换和绑定,本章将针对 Spring MVC 中 JSON 类型的数据交互和 RESTful 支持进行详细讲解。

JSON 数据交互

JSON 是近几年才流行的一种新的数据格式,它与 XML 非常相似,都是用于存储数据的; 但 JSON 相对于 XML 来说,解析速度更快,占用空间更小。 因此在实际开发中,使用 JSON 格式的数据进行前后台的数据交互是很常见的。 下面将对 Spring MVC 中 JSON 数据的交互内容进行详细的讲解。

  • JSON 概述

JSON ( JavaScript Object Notation , JS 对象标记)是一种轻量级的数据交换格式。 它是基于 JavaScript 的一个子集,使用了 C、 C++、 C#、 Java、 JavaScript、 Perl、 Python 等其他语言的约定,采用完全独立于编程语言的文本格式来存储和表示数据。 这些特性使 JSON 成为理想的数据交互语言,它易于阅读和编写,同时也易于机器解析和生成。
与 XML 一样, JSON 也是基于纯文本的数据格式。 刚开始大家可以使用 JSON 传输一个简单的 String、 Number、 Boolean,也可以传输一个数组或者一个复杂的 Object 对象。
JSON 有如下两种数据结构。

  1. 对象结构
    对象结构以"{"开始,以"}"结束。 中间部分由 0 个或多个以英文","分隔的 name/value 对构成(注意 name 和 value 之间以英文": "分隔),其存储形式如图所示。



    对象结构的语法结构代码如下。

{
    key1:value1,
    key2:value2,
    ...
}

其中关键字 (key) 必须为 String 类型,值 (value) 可以是 String、 Number、 Object、 Array 等数据类型。 例如,一个 address 对象包含城市、街道、 邮编等信息,使用 JSON 的表示形式如下。

{"city":"Beijing","street":"Xisanqi","postcode":l00096 } 
  1. 数组结构
    数组结构以"["开始,以"]"结束。 中间部分由 0 个或多个以英文","分隔的值的列表组成,其存储形式如图所示。



    数组结构的语法结构代码如下。

[
   value1,
   value2,
   ...
]

例如,一个数组包含了 String、 Number、 Boolean、 null 类型数据,使用 JSON 的表示形式如下。

  ["abc",12345,false,null] 

上述两种(对象、数组)数据结构也可以分别组合构成更为复杂的数据结构。 例如:一个 person 对象包含 name、 hobby 和 address 对象,其代码表现形式如下。

  {
      "name": "zhangsan" 
      "hobby" : ["篮球","羽毛球","游泳"] 
      "address" : {
          "city":"ShenYang"
          "street":"RenMinDaJie" 
          "postcode":100096 
      }
  }

需要注意的是,如果使用 JSON 存储单个数据(如 "abc" ),一定要使用数组的形式,不要使用 Object 形式,因为 Object 形式必须是"名称:值"的形式。

  • JSON 数据转换

为了实现浏览器与控制器类( Controller )之间的数据交互, Spring 提供了一个 HttpMessageConverter接口来完成此项工作。 该接口主要用于将请求信息中的数据转换为 一个类型为 T 的对象,并将类型为 T 的对象绑定到请求方法的参数中,或者将对象转换为响应信息传递给浏览器显示。
Spring 为 HttpMessageConverter接口提供了很多实现类,这些实现类可以对不同类型的数据进行信息转换。 其中 MappingJackson2HttpMessageConverter 是 Spring MVC 默认处理 JSON 格式请求响应的实现类。 该实现类利用 Jackson 开源包读写 JSON 数据,将 Java 对象转换为 JSON 对象和 XML 文档,同时也可以将 JSON 对象和 XML 文档转换为 Java 对象。 要使用 MappingJackson2HttpMessageConverter 对数据进行转换,就需要使用 Jackson 的开源包,开发时所需的开源包及其描述如下所示。


以上 3 个 Jackson 的开源包大家以通过链接
"http://mvnrepository.com/artifact/com.fasterxm1.jackson.core" 下载得到。
在使用注解式开发时,需要用到两个重要的 JSON 格式转换注解,分别为@RequestBody 和@ResponseBody ,关于这两个注解的说明如表所示。

注解 说明
@RequestBody 用于将请求体中的数据绑定到万法的形参中。 该注解用在方法的形参上
@ResponseBody 用于直接返回陀turn 对象。 该注解用在方法上

了解了 Spring MVC 中 JSON 数据交互需要使用的类和注解后,接下来通过一个案例来演示如何进行 JSON 数据的交互,具体实现步骤如下。
( 1 ) 创建项目并导入相关 JAR 包。 使用 Eclipse 创建一个名为 springmvc04 的 Web 项目,然后将 Spring MVC 相关 JAR 包、 JSON 转换包添加到项目的 lib 目录中,并发布到类路径下。 添加后的 lib 目录如图所示。



( 2 ) 在 web.xml 中,对 Spring MVC 的前端控制器等信息进行配置,文件如下所示。



       springmvc04
       
          index.jsp
       
       
       
          springmvc
          
              org.springframework.web.servlet.DispatcherServlet
          
          
          
              contextConfigLocation
              classpath:springmvc-config.xml
          
          
          1
       
       
          springmvc
          /
            

( 3 )在 src 目录下,创建 Spring MVC 的核心配置文件 springmvc-config.xml ,编辑后的代码文件如下所示。



  
  
  
   
  
  
  
  
      
       
      
       
  

在文件中,不仅配置了组件扫描器和视图解析器,还配置了 Spring MVC 的注解驱动 和静态资源访问映射。 其中配置会自动注册 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 两个 Bean ,并提供对读写 XML 和读写 JSON 等功能的支持。 元素用于配 置静态资源的访问路径。 由于在 web.xml 中配置的"/"会将页面中引入的静态文件也进行拦截, 而拦截后页面中将找不到这些静态资源文件,这样就会引起页面报错。 而增加了静态资源的访问映射配置后,程序会自动地去配置路径下找静态的内容。
中有两个重要属性 location 和 mapping ,关于这两个属性的说明如下表所示。

属性 说明
location 用于定位需要访问的本地静态资源文件路径,具体到某个文件夹
mapping 匹配静态资源全路径,冥中"/**"表示文件夹及其子文件夹下的某个具体文件

( 4 )在 src 目录下,创建一个 com.neuedu.po 包,并在包中创建一个 User 类,该类用于封装 User 类型的请求参数,编辑后文件如下所示。

package com.neuedu.po;
/**
* 用户POJO
*/
public class User {
  private String username;
  private String password;
  public String getUsername() {
      return username;
  }
  public void setUsername(String username) {
      this.username = username;
  }
  public String getPassword() {
      return password;
  }
  public void setPassword(String password) {
      this.password = password;
  }
  @Override
  public String toString() {
      return "User [username=" + username + ", password=" + password + "]";
  }
}

在文件中,定义了 username 和 password 属性,及其对应的 getter/setter 方法,同时为了方便查询结果重写了 toString() 方法。
( 5 )在 WebContent 目录下,创建页面文件 index.jsp 来测试 JSON 数据交互,编辑后文件如下所示。

<%@ page language="java" contentType="text/html; charset=utf-8"
   pageEncoding="utf-8"%>




测试 JSON交互




  
用户名:
密  码:

在文件中,编写了一个测试 JSON 交互的表单,当单击"测试 JSON 交互"按钮时, 会执行页面中的 testJson()函数。在函数中使用了 jQuery 的 AJAX 方式将 JSON 格式的用户名和密码传递到以 "/testJson" 结尾的请求中。 需要注意的是,在 AJAX 中包含了 3 个特别重要的属性,其说明如下。

  • data: 即请求时携带的数据,当使用 JSON 格式时,要注意编写规范。
  • contentType: 当请求数据为 JSON 格式时,值必须为 application/json。
  • dataType: 当响应数据为 JSON 时,可以定义 dataType 属性,并且值必须为 json。 其中 dataType: "json"也可以省略不写 ,页面会自动识别响应的数据格式。

小提示:在上述测试页面 index.jsp 中使用的是jQuery 的 AJAX 进行的 JSON 数据提交和响应,所以还需要引入 jquery.js 文件。 本示例是引入了 WebContent 目录下js 文件夹张的 jquery-l.11.3.min.js,大家可以自行下载。
( 6 )在 src 目录下,创建一个 com.neuedu.controller 包,在该包下创建一个用于用户操作的控制器类 UserController,编辑后的代码文件如下所示。

package com.neuedu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.neuedu.po.User;
@Controller
public class UserController {
  /**
   * 接收页面请求的 JSON 数据,并返回 JSON 格式结果
   */
  @RequestMapping("/testJson") 
  @ResponseBody 
  public User testJson(@RequestBody User user){
      //打印接收的 JSON 格式数据
      System.out.println(user);
      //返回 JSON 格式的响应
      return user;
  }
}

在文件中,使用注解方式定义了一个控制器类,并编写了接收和响应 JSON 格式数据 的 testJson() 方法,在方法中接收并打印了接收到的 JSON 格式的用户数据,然后返回了 JSON 格式的用户对象。
方法中的@RequestBody 注解用于将前端请求体中的 JSON 格式数据绑定到形参 user 上, @ResponseBody 注解用于直接返回 User 对象(当返回 POJO 对象时,会默认转换为 JSON 格 式数据进行响应)。
( 7 )将 springmvc04 项目发布到 Tomcat 服务器并启动,在浏览器中访问地址 http://localhost:8880/springmvc04/ ,其显示效果如图所示。


在两个输入框中分别输入用户名 "jack" 和密码 "123456" 后,单击"测试 JSON 交互" 按钮,当程序正确执行时,页面中会弹出显示用户名和密码的弹出框,如图所示。

与此同时, Eclipse 的控制台中也会显示相应数据,如图所示。

从图中的显示结果可以看出,编写的代码已经正确实现了 JSON 数据交互, 可以将 JSON 格式的请求数据转换为方法中的 Java 对象,也可以将 Java 对象转换为 JSON 格式的响应数据。
多学一招

  • 使用标签方式的 JSON 转踉器配置
    在配直 JSON 转换器时 , 除了常用的方式配置外,还可以使用 标签的方式进行显示的配置。 具体配直方式如下 。
    从上述示例可以看出 , 使用 标签配直方式配置 JSON 转换器时, 需要同时配直处理器映射器和处理器适配器,并且 JSON 转换器是配置在适配器中。
  • 配置静态资源访问的万武
    除了使用 元素可以实现对静态资源的访问外,还有另外两种静态资源访问 的配直方式,具体分别如下。



    ( 1 )使用 标签。
    在 springmvc-config.xml 文件中,使用 标签,具体如下。

  

在 springmvc-config.xml 中配直后,会在 SpringMVC 上下文中定义一个 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler (即默认的 Servlet 请求处理器)。 它会像一个检查员,对进入 DispatcherServlet 的 URL 进行筛查. 如果 发现是静态资源的请求,就将该请求转由 Web 服务器默认的 Servlet 处理,默认的 Servlet 就会对这些静态资源放行;如果不是静态资源的请求,才由 DispatcherServlet 继续处理。

  • 注意
    一般 Web 服务器默认的 Servlet 名称是"default",因此 DefaultServletHttpRequestHandler 可以找到它。如果使用的 Web应用服务器默认的 Servlet 名称不是"default",则需要通过default-servlet-name属性显示指定,具体方式如下。

    而 Web 服务器的 Servlet 名称是由使用的服务器确定的,常用服务器及其 Servlet 名称如下。
    • Tomcat、 Jetty、 JBoss 和 and GlassFish 默认 Servlet 的名称一一 "default"
    • Google App Engine 默认 Servlet 的名称一一"_ah_default"
    • Resin 默认 Servlet 的名称一一"resin-file"。
    • WebLogic 默认 Servlet 的名称一一 "FileServlet"。
    • WebSphere 默认 Servlet 的名称一一"SimpleFileServlet"。

( 2 )激活 Tomcat 默认的 Servlet 来处理静态文件访问 。 激活 Tomcat 默认的 Servlet 时,需要在 web.xml 中添加以下内容.



在上述代码中,配置了 元素来激活 Tomcat 默认的 Servlet 来处理静态文件,我们还可以根据需要继续追加,此种配置方式和上一种方式本质上是一样的,都是使用 Web 服务器默认的 Servlet 来处理静态资源文件的访问。其中 Servelt 名称(即元素的值)也是由使用的服务器来确定的,不同的服务器需要使用不同的名称。 以上 3 种静态资源访问的自己直方式不同,并且各有优缺点,具体如下。
• 第一和第三种配直方式可以选择性的释放静态资源。
• 第二种配直方式配直相对简单,只需要一行代码,就可以释放所有静态资源。
• 第二和第二种配直方式会导致项目移植性较差,需要根据具体的 Web 服务器来支改 Servlet 名称。
• 第三种配置方式运行效率更高,因为服务器启动时已经加载了 web.xml 中的静态资源 。
在实际开发中,更为常用的配直还是第一种(即案例中的)配置方式,这样就不需要考虑 Web 服务器的问题了 。

RESTful 支持

Spring MVC 除了支持 JSON 数据交互外,还支持 RESTful 风格的编程。 接下来的两个小节就对 Spring MVC 中 RESTful 风格的编程进行详细的讲解。

  • 什么是 RESTful

RESTful 也称之为 REST ( Representational State Transfer ),可以将它理解为一种软件架构风格或设计风格,而不是一个标准。
简单来说, RESTful 风格就是把请求参数变成请求路径的一种风格。 例如,传统的 URL 请求格式为:

http://.../queryltems?id=1

而采用 RESTful 风格后,其 URL 请求为:

http://.../queryltems/1

从上述两个请求中可以看出, RESTful 风格中的 URL 将请求参数 id=1 变成了请求路径的一部分,并且 URL 中的 queryltems 也变成了 items ( RESTful 风格中的 URL 不存在动词形式的路径,如 queryltems 表示查询订单,是一个动词,而 items 表示订单,为名词)。
RESTful 风格在 HTIP 请求中,使用 put、 delete、 post 和 get 方式分别对应添加、删除、 修改和查询的操作。 不过目前国内开发,还是只使用 post 和 get 方式来进行增删改查操作。

  • 应用案例一一用户信息查询

本案例将采用 RESTful 风格的请求实现对用户信息的查询,同时返回 JSON 格式的数据。 其具体实现步骤如下。
( 1 )在控制器类 UserController 中,编写用户查询方法 selectUser() ,代码如下所示。

  /**
   * 接收 RESTful 风格的请求,其接收方式为 GET 
   */
  @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
  @ResponseBody 
  public User selectUser(@PathVariable("id") String id){
      //查看数据接收
      System.out.println("id = "+id);
      User user = new User();
      //模拟根据id查询出到用户对象数据
      if(id.equals("1234")){
          user.setUsername("tom");
      }
      //返回 JSON格式的数据
      return user;    
  }

在上述代码中, @RequestMapping(value="/user/{id}",method=RequestMethod.GET)注解用于匹配请求路径(包括参数)和方式。 其中 value="/user/{id}"表示可以匹配以 "/user/{id}" 结尾的请求, id 为请求中的动态参数; method=RequestMethod.GET 表示只接收 GET 方式的请求。 方法中的@PathVariable("id")注解则用于接收并绑定请求参数,它可以将请求 URL 中的变量映射 到方法的形参上,如果请求路径为 "/user/{id}" ,即请求参数中的 id 和方法形参名称 id 一样,则@PathVariable 后面的“("id")” 可以省略。
( 2 )在 WebContent 目录下,编写页面文件 restful.jsp ,在页面中使用 AJAX 方式通过输入的用户编号来查询用户信息,文件如下所示。

<%@ page language="java" contentType="text/html; charset=utf-8"
   pageEncoding="utf-8"%>




RESTful 测试




  
编号:

在文件中,在请求路径中使用了 RESTful 风格的 URL,并且定义了请求方式为 GET。
( 3 )将项目发布到 Tomcat 服务器并启动,在浏览器中访问地址 http://localhost:8080/springmvc04/restful.jsp ,其显示效果如图所示。


在输入框中输入编号 "1234" 后,单击"查询"按钮,程序正确执行后,浏览器会弹出用户信息窗口,如图所示。

如果客户端使用的是火狐浏览器,使用 Firebug 查看请求地址,会发现请求的 URL 就是我们所需要的 RESTful 风格的路径,如图所示。

与此同时, Eclipse 的控制台中,也打印出了请求的参数信息,如图所示。

从图中的显示结果可以看出,我们已经成功地使用 RESTful 风格的请求查询出了用户信息。

本章小结

本章主要对 Spring MVC 中的 JSON 数据交互和 RESTful 风格的请求进行了详细的讲解。 首先简单介绍了 JSON 的概念、 作用和结构,然后通过案例讲解了 Spring MVC 中如何实现 JSON 数据的交互。 接下来讲解了什么是 RESTful ,最后通过用户信息查询案例来演示 RESTful 的实际使用。 通过本章的学习,大家可以掌握 Spring MVC 中的 JSON 数据交互和对 RESTful 风格支持, 这对今后实际开发有极大的帮助。

你可能感兴趣的:(第 14 章 JSON 数据交互和 RESTful 支持)