SpringMVC(3):传递 Json

SpringMVC(3)传递Json(未修改版本)

文章目录

引出:如果你想使用 postman(在前端)传递一个二维数组,二维顺序表等这类复杂的数据,正常的传递,是传不了的,这时候,需要使用到 json了。

1. json的简单介绍

jSON概念

JSON:JavaScript Object Notation(JavaScript 对象表示法)

JSON 是一种轻量级的数据交换格式,专门用于客户端与服务器端之间的数据交互场景。

简单来说:JSON 本质是一种基于文本的字符串格式,有自身固定的语法规则,通过文本形式描述对象或数组的信息。它不依赖于特定编程语言,核心作用是在不同语言的程序之间实现数据的传递与交换。

json示例

json表示对象的方式

json 复制代码
{
"name":"zhangsan",
"age":"19",
"gender":"male"
}

json的简单语法

  1. 数据以键值对(Key/Value) 的形式组织;
  2. 键(Key)与值(Value)之间使用英文冒号 : 分隔;
  3. JSON 对象使用英文大括号 {} 表示
  4. JSON 数组使用英文中括号 [] 表示;
  5. 值(Value)可以是对象、数组等类型,数组中可包含多个 JSON 对象。

json的两种结构

  1. 对象:对象是由大括号 {} 包围的无序键值对集合。对象以左花括号 { 开始,以右花括号 } 结束。每个"键"后跟一个冒号 :,不同键值对之间用逗号 , 分隔。
  2. 数组:数组是由中括号 [] 包围的有序值(value)集合。数组以左中括号 [ 开始,以右中括号 ] 结束,各个值之间用逗号 , 分隔。

json的优点:

  1. 简单易用:JSON 语法简洁明了,易于理解与编写,能够快速实现数据的序列化与交换。
  2. 跨平台支持:JSON 被绝大多数编程语言原生支持,可轻松在不同平台和语言之间进行数据交换与传输。
  3. 轻量高效:相比 XML,JSON 格式更加紧凑,数据体积更小,在网络传输中占用带宽更少,有助于提升传输效率。
  4. 结构灵活:JSON 支持嵌套对象、数组等复杂数据结构,具有良好的可扩展性,便于构建和表达多样化数据。
  5. 安全性高:JSON 是一种纯文本数据格式,不包含可执行代码,因此不会触发脚本执行,有效避免了潜在的安全风险。

凭借上述优势,JSON 已成为 Web 应用开发中的主流数据格式,广泛应用于前后端通信、RESTful API 数据传输等场景。

在线JSON校验格式化工具

  1. bejson
  2. jsoncn

2. JSON字符串和Java对象互转

常见的json和对象转换的工具

  1. gson(谷歌出的),使用说明的网址:
    gson

  2. fastjson(阿里),对应网址:
    fastjson

    或者百度搜索:fastjson使用

  3. jackson,SpringMVC框架也集成了JSON的转换⼯具,如果你创建的是 springboot项目 我们可以直接使用,来完成JSON字符串和Java对象的互转,如果不是,则需要在 pom.xml 引依赖:

java 复制代码
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>2.13.5</version>
</dependency>

JSON字符串和Java对象互转的应用

我们这个应用,和项目本身是没有关系的,所以,我们可以写在测试代码中:

以上,和我们平常普通java代码没区别,接下来,用一种新的方式,来进行测试。

使用 @Test 注释

@Test 这个注释,是开发人员进行单元测试的时候,使用到的一个注解。

只用这个注解,就类似于main 方法,可以运行的。

@Test 和 main 方法的区别

@Test 在一个类当中,可以存在多个,可以测试多个案例

main方法,在一个类中,只可以存在一个

这里讲的测试,是开发人员做的测试

测试人员进行测试的方式,和这个是完全不同的。

Java对象转 json(序列化)

这里我们使用到一个新的类:ObjectMapper类,用于 java对象转为json的一个类

还会使用到一个新的方法:writeValueAsString(),用于 java对象转为json的一个方法

json 转为 java对象(反序列化)

这里的类仍然是:ObjectMapper类

这里需要使用到一个新的方法:readValue(s,User.class)

第一个参数:要转化的json字符串

第二个参数:要转化的Java对象

代码:

java 复制代码
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * Date: 2025-10-10
 * Time: 下午9:53
 */
public class JsonTest {

    @Test
    public void UserchangeJson() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        //创建一个 Java 对象
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        user.setGender("男生");
        //Java对象转 Json
        String s = objectMapper.writeValueAsString(user);
        System.out.println(s);
    }

    @Test
    public void JsonchangeUser() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        //创建一个 JSON 字符串
        String json = "{\"name\":\"张三\",\"age\":18,\"gender\":\"男生\"}";
        //JSON 转为 Java对象
        User user = objectMapper.readValue(json, User.class);
        System.out.println(user);
    }
}

3. json的传递使用

这里我们要学一个新的注解:@RequestBody

@RequestBody 这个注解表示:我们后端代码要接收的数据,是一个json数据。

@RequestBody的作用是:将请求体中的数据绑定到方法的参数上,通常用于接收前端发送的 JSON 或 XML 格式的数据

接收json数据的代码:

Postman 传递json数据的方式:

可以看到,后端正确接收了

注意事项:

json格式没有要求

两种编写格式,都可以接收到json数据。

json数据,和类对象的属性,没有顺序对应要求

json数据中,sex 和 name 的顺序,和类的属性的定义顺序不一样,也能够接收数据。

json数据,和类对象的成员名,要相同

和之前的数据一样,传递的时候,传递数据的数据名称,要和后端的变量的名称,要一样。

可能报错的情况

单元测试用例的时候,没有默认的无参构造方法

测试单元用例的时候,如果已经有一个其他参数的构造方法,没有再指定一个无参的构造方法,运行单元测试,会出错。

原因:

java 复制代码
User user = objectMapper.readValue(s,User.class);

这条语句,会先构造一个空的User对象,构造空的User对象的时候,需要空的构造方法(无参构造方法)。

如果类当中,没有任何的构造方法,jdk 会默认提供一个无参的构造方法。

你加了一个有参数的构造方法之后,jdk 就不会给你提供一个无参构造方法了,就会构造失败。

java 复制代码
String s = "{\"name\":\"zhangsan\",\"sex\":1,\"age\":18}";

之后,才会解析这个字符串,解析里面的数据,对应到刚才创建的那个对象上面。

这就是一种规范:创建类的时候,无参的构造方法,toString什么的,都给加上。

但是,后面会学到一种注解(lombok 提供的 @Data注解),让这些东西都不用写了。

问题:

json数据传过来后端,java是通过类的构造方法赋值,还是set方法赋值
  1. 假设使用 类的构造方法 赋值,去掉所有的set方法

  2. 假设使用 set方法 赋值,去掉构造方法

注意:这种假设,不一定成立,当你去掉所有的构造方法之后,jdk会默认提供一个无参的构造方法,你不知道,是不是这个无参的构造方法起的作用。

总结:构造方法和 set 方法,都会使用到。

总之,这个问题,不同太关心,不要转牛角尖,Springboot 的学习不在这些问题上。

代码:

java 复制代码
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * Date: 2025-10-10
 * Time: 下午6:50
 */


@RequestMapping("request")
@RestController
public class RequestController {

//    客户端传递一个参数,服务器接收一个参数(字符串)
    @RequestMapping("/r1")
    public String r1(String keyword) {
        return "接收参数:" + keyword;
    }

//    客户端传递两个参数,服务器接收两个参数
    @RequestMapping("/r2")
    public String r2(String username,String password) {
        System.out.println("用户名" + username);
        System.out.println("密码:" + password);
        return "用户名:" + username  + "密码:" + password;
    }

//    客户端传递 Integer 参数
    @PostMapping("/r3")
    public String r3(Integer number) {
        return "接收参数:" + number;
    }

//    客户端传递 int类型 的变量
    @PostMapping("/r4")
    public String r4(int number) {
        return "接收参数:" + number;
    }

//    客户端传递一个 对象(多个变量)
    @RequestMapping("/r5")
    public String r5(User user) {
        return "接收一个 user对象:" + user.toString();
    }

//    @RequestMapping("r6")
////    前端传递 q 给后端,后端使用不同名字的参数接收(@RequestParam)
////    使用 @RequestParam 之后,这个参数,是必传参数(一定要传参数),不然会报错
//    public String r6(@RequestParam("q") String keyword) {
//        return "接收参数:" + keyword;
//        // q 是前端的参数,后端不用(输入的时候,参数是 q)
//        // 后端使用 keyword 来接收前端的参数 q 的值,后续使用 keyword 作为变量,进行操作
//    }

    @RequestMapping("r6")
//    手动设置,取消必传限制
    public String r6(@RequestParam(value = "q",required = false) String keyword) {
        return "接收参数:" + keyword;
        // q 是前端的参数,后端不用(输入的时候,参数是 q)
        // 后端使用 keyword 来接收前端的参数 q 的值,后续使用 keyword 作为变量,进行操作
    }

    //    客户端传递一个 数组
    @RequestMapping("/r7")
    public String r7(String[] arr) {
        return "接收参数的数组 arr:" + Arrays.toString(arr);
    }

    @RequestMapping("/r8")
    public String r8(@RequestParam List<Integer> list) {
        return "接收一个集合数据:" + list;

    }

    @RequestMapping("/r9")
//    客户端传递一个JSON数据,服务器使用 User对象接收(使用 @RequestBody 绑定)
    public String r9(@RequestBody User user) {
        return user.toString();
    }

    
}

4. 总结

这里,学到了两个新的注释:

@Test 这个注释,是开发人员进行单元测试的时候,使用到的一个注解。

@RequestBody 这个注解表示:将请求体中的数据绑定到方法的参数上,通常用于接收前端发送的 JSON 或 XML 格式的数据

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!

下一篇博客:SpringMVC(4)获取参数,上传文件

相关推荐
tkevinjd2 小时前
5-Web基础
java·spring boot·后端·spring
树码小子2 小时前
SpringMVC(4):获取参数,上传文件
spring·mvc
好好沉淀2 小时前
Spring Boot Admin:微服务的“健康体检中心
spring boot·spring·架构·springbootadmin
爱吃山竹的大肚肚2 小时前
异步导出方案
java·spring boot·后端·spring·中间件
晚风_END3 小时前
postgresql数据库|连接池中间件pgbouncer的部署和配置详解
数据库·后端·spring·postgresql·中间件·个人开发
梵得儿SHI3 小时前
(第九篇)Spring AI 核心技术攻坚:安全防护 企业级 AI 应用的风控体系之全链路防护(API 安全到内容合规)
java·人工智能·安全·spring·安全防护·springai·企业级ai
Mr.朱鹏12 小时前
Nginx路由转发案例实战
java·运维·spring boot·nginx·spring·intellij-idea·jetty
代码丰16 小时前
SpringAI+RAG向量库+知识图谱+多模型路由+Docker打造SmartHR智能招聘助手
人工智能·spring·知识图谱
wr20051416 小时前
第二次作业,渗透
java·后端·spring