SpringMVC系列--JSON数据交互和Restful支持

JSON数据交互

JSON与XML非常相似,都是用于存储数据的,但JSON相对于XML来说,解析速度更快,占用空间更小。

JSON概述

JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交互格式。采用完全独立于编程语言的文本格式来存储和表示数据。
与XML一样,JSON也是基于纯文本的数据格式。我们可以使用JSON传输一个简单的String、Number、Boolean,也可以传输一个数组或者一个复杂的Object对象。JSON有两种数据结构:对象结构和数组结构。

对象结构

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

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

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

{"city":"邵阳","street":"北塔区"}
数组结构

数组结构的语法结构如下:

{
	value1,
	values2,
	.....
}

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

{"jack",27,false,null}

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

{
	"name":"小鑫",
	"hobby":["编程","UI"],
	"address":{
		"city":"邵阳",
		"street":"北塔区"
	}
}

JSON数据转换

为了实现浏览器与控制器类(Controller)之间的数据交互,Spring提供了HttpMessageConverter接口,该接口主要用于将请求消息中的数据转换为一个类型为T的对象,并将类型为T的对象绑定到请求方法的参数中,或者将对象转换为响应消息传递给浏览器显示。

Spring为HttpMeesageConverter< T>接口提供了很多实现类,这些实现类可以对不同类型的数据进行信息转换。其中MappingJacksona2HttpMessageConverter是SpringMVC默认处理JSON格式请求响应的实现类。该实现类利用jackson开源包读写Json数据,将Java对象转换为JSON对象和XML文档,同时可以将JSON对象和XML文档转换为Java对象。

因此我们需要再pom.xml中导入jackson相关的坐标,代码如下:

 <!--json和javabean对象相互转换所需要的jar包-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>

在使用注解式开发时,需要用到两个重要的JSON格式转换注解@RequestBody和@ResponseBody。

  • @RequestBody:用于将请求体的数据绑定到方法的形参中,该注解用在方法的形参上。
  • @ResponseBody:用于直接返回return对象,该注解用在方法上。

代码实现

构造环境

创建Maven项目,并导入pom.xml坐标。

  <dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <!-- 版本锁定 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.6.RELEASE</version> </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.6.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>
    <!--json和javabean对象相互转换所需要的jar包-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
</dependencies>
web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
  <display-name>Archetype Created Web Application</display-name>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!--配置编码过滤器-->
  <filter>
    <filter-name>CharacterEncodeingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodeingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <servlet>
    <!--配置前端过滤器-->
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--初始化时加载配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc-config.xml</param-value>
    </init-param>
    <!--表示容器来启动时立即加载Servlet-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">


    <!--定义扫描器-->
    <context:component-scan base-package="com.ssm.controller"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--配置静态资源的访问映射,此配置中的文件将不被前端控制器拦截-->
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>

</beans>

上述代码中,不仅配置了组件扫描器和视图解析器,还配置了Spring MVC的注解驱动< mvc:annotation-driven/>和静态资源访问映射< mvc:resources…/>。

其中< mvc:annotation-driven/>配置会自动注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter两个Bean,并提供对读写XML和读写JSON等功能的支持。

< mvc:resources…/>元素用于配置静态资源的访问路径。由于在web.xml中配置的"/"会对页面中引入的静态文件进行拦截,而拦截后页面中将找不到这些静态资源文件,因此会引起页面报错。而增加了静态资源的访问映射配置后,程序会自动地去配置路径下找静态的内容。

< mvc:resources…/>中两个重要属性location和mapping

  • location:用于定位需要访问的本地静态资源文件路径,具体到某个文件夹。
  • mapping:匹配静态资源全路径,其中"/"表示文件夹及其子文件下的某个具体文件。
Customer.java

创建Customer类,该类用于封装Customer类型的请求参数,代码如下:

package com.ssm.po;


//客户类Customer
public class Customer {
    private  Integer id;
    private  String loginname; //客户登录名
    private  String nickname; //昵称
    private  String password;//密码

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLoginname() {
        return loginname;
    }

    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", loginname='" + loginname + '\'' +
                ", nickname='" + nickname + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

json.jsp

在webapp目录下创建文件json.jsp来测试JSON数据交互,这样可以直接在浏览器中访问json.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试JSON交互</title>
    <script type="text/javascript" src="https://www.imooc.com/static/lib/jquery/1.9.1/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn").click(function () {
                //获取输入的客户信息
                var loginname=$("#loginname").val();
                var password=$("#password").val();
                $.ajax({
                    url:"${pageContext.request.contextPath}/testJson",
                    type:"post",
                    //data表示发送的数据
                    data:JSON.stringify({loginname:loginname,password:password}),

                    //定义发送请求的数据格式为JSON字符串
                    contentType:"application/json;charset=UTF-8",
                    //定义回调响应的数据格式为JSON字符串,该属性可以省略
                    dataType:"json",
                    //成功响应的结果
                    success:function (data) {
                        if(data!=null){
                            alert("您输入的登录名为:"+data.loginname+"密码为 "+data.password);
                        }
                    }
                })
            })
        })

    </script>
</head>
<body>

        登录名:<input type="text" name="loginname" id="loginname"/><br/>
        密码: <input type="text" name="password" id="password"/> <br/>
        <input type="button" value="测试JSON" id="btn">
</body>
</html>

当点击"测试JSON交互"按钮时,我们使用了JQuery的AJAX方式将JSON格式的登录名和密码传递到以"/testJson"结尾的请签字。

在AJAX有3个特别重要的属性

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

注意: json.jsp还需要引入jquery.js文件。

CustomerController.java
package com.ssm.controller;

import com.ssm.po.Customer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class CustomerController {

    //接收页面请求的JSON数据,并返回JSON数据格式
    @RequestMapping(value = "/testJson",method = RequestMethod.POST)
    public @ResponseBody Customer testJson (@RequestBody Customer customer){
        //打印接收到的JSON格式数据
        System.out.println(customer);
        return  customer;
    }
}

方法中的@RequestBody注解用于将前端请求体中的JSON格式数据绑定到形参customer上,@ResponseBody注解用于直接返回Custome对象(当返回POJO对象时,会默认转换为JSON格式数据进行响应)。

启动项目,访问地址"http://localhost:8081/json.jsp", 显示效果如下:
在这里插入图片描述
当我们输入用户名和密码后,点击"测试JSON"按钮,如果页面弹出一个对话框,说明我们已经实现了JSON数据交互,可以将JSON格式的请求数据转换为方法中的Java对象,也可以将Java对象转换为JSON格式的响应数据。

RESTful支持

什么是RESTful

RESTful也称为REST(Representational State Transfer),可以将它理解为一种软件架构风格或设计风格。

RESTful风格就是把请求参数变成请求路径的一种风格。例如:传统的URL请求格式如下:

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

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

http://..../items/1

从上述两个请求中可以看出,RESTful风格中的URL将请求参数id=1变成了请求路径的一部分,并且URL中的queryItems也变成了items(RESTful风格中的URL不存在动词形式的路径).

RESTful风格在HTTP请求中使用put、delete、post和get方法分别对应添加、删除、修改和查询的操作。

代码实现—查询客户信息

CustomerController.java
//接收RESTful风格的请求,其接收方式为GET
    @RequestMapping(value = "/customer/{id}",method = RequestMethod.GET)
    @ResponseBody
    public Customer selectCustomer(@PathVariable("id") Integer id){
        //查看接收数据
        System.out.println(id);
        Customer customer = new Customer();
        //模拟根据id查询出客户对象数据
        if(id==10){
            customer.setLoginname("xiaoxin");
        }
        //返回JSON格式的数据
        return  customer;
    }

在上述代码中,value="/user/{id}“表示可以匹配以”/user/{id}"结尾的请求,id为请求中的动态参数;method=RequestMethod.Get表示只接收GET方式的请求。

方法中的@PathVariable(“id”)注解则用于接收并绑定请求参数,它可以将请求URL中的变量映射到方法的形参上,如果请求参数中的id和方法形参名称id一样,则@PathVariable后面的(“id”)可以省略。

例如,在浏览器中访问 http://localhost:8081/user/1,那么方法中的id就为1,如果访问的是user/2,那么方法中的id就为2。

restful.jsp

在webapp下创建restful.jsp文件,这样浏览器可以直接访问restful.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>RESTful测试</title>
    <script type="text/javascript" src="https://www.imooc.com/static/lib/jquery/1.9.1/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn").click(function () {
                //获取输入查询编号
                var id = $("#number").val();
                //发送ajax请求
                $.ajax({
                    url:"${pageContext.request.contextPath}/customer/"+id,
                    type:"GET",
                    //定义回调响应的数据格式为JSON字符串,该属性可以省略
                    dataType:"json",
                    success:function (data) {
                        if(data.loginname!=null){
                            alert("查询的客户为"+data.loginname)
                        }else{
                            alert("没找到客户编号为"+id+"的客户")
                        }
                    }
                })
            })
        })
    </script>
</head>
<body>
    客户编号:<input type="text" name="number" id="number"/> <br/>
    <input type="button" value="查询" id="btn">
</body>
</html>

启动项目,访问地址http://localhost:8081/restful.jsp,页面如下:
在这里插入图片描述
点击查询按钮,浏览器会弹出客户信息窗口,说明我们已经成功地使用RESTful风格的请求查询出了客户信息。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值