【JavaEE】Spring Web MVC(上)

什么是Spring Web MVC?

官方对于Spring MVC的描述是这样的:

Spring Web MVC是基于Servlet API 构建的原始Web框架,从一开始就包含在Spring框架中。它的正式名称"Spring Web MVC"来自其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC"。

什么是Servlet呢?

Servlet是一种实现动态页面的技术。准确来讲Servlet是一套Java Web开发的规范,或者说是一套Java Web开发的技术标准。只是规范并不能做任何事情,必须要有人去实现它。所谓实现Servlet规范,就是真正编写代码去实现Servlet规范提到的各种功能,包括类、方法、属性等。

Servlet规范是开放的,除了Sun公司,其他公司也可以实现Servlet规范,目前常见的实现了Servlet规范的产品包括Tomcat、Weblogic、Jetty、WebSphere等,它们都被称为"Servlet容器"。Servlet容器用来管理程序员编写的Servlet类

从上述定义我们可以得出一个信息:Spring Web MVC是一个Web框架

下面咱们简称之为:Spring MVC

然而要真正的理解什么是Spring MVC?我们首先要搞清楚什么是MVC?

MVC定义

MVC是Model View Controller的缩写 ,它是软件工程中的一种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分

**·View(视图)**指在应用程序中专业用来与浏览器进行交互,展示数据的资源

**·Model(模型)**是应用程序的主体部分,用来处理程序中数据逻辑的部分

**·Controller(控制器)**可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型

举个例子:

比如去饭店吃饭

客户进店之后,服务员来接待客户点餐,客户点完餐之后,把客户菜单交给前厅,前厅根据客户菜单给后厨下达命令。后厨负责做饭,做完之后,再根据菜单告诉服务员,这是X号餐桌客人的饭

在这个过程中

服务员就是View(视图),负责接待客户,帮助客户点餐,以及给顾客端饭

前厅就是Controller(控制器),根据用户的点餐情况,来选择给哪个后厨下达命令

后厨就是Model(模型),根据前厅的要求来完成客户的用餐需求

什么是Spring MVC?

MVC是一种架构设计模式,也是一种思想,而Spring MVC是对MVC思想的具体实现。除此之外。Spring MVC还是一个Web框架

总结来说,Spring MVC是一个实现了MVC模式的Web框架

所以,Spring MVC主要关注有两个点:

1.MVC

2.Web框架

Spring MVC全称是Spring Web MVC

其实,Spring MVC我们在前面已经用过了,在创建Spring Boot项目时,我们勾选的Spring Web框架其实就是Spring MVC框架:

可以看到,Spring Web的介绍是:

Build Web,including RESTful,applications using Spring MVC。Uses Apache Tomcat as the default embedded container

这时候可能有些学生就懵了,前面创建的不是Spring Boot项目吗?怎么又变成了Spring MVC项目?他们之间到底有着什么样的关系?

Spring Boot只是实现Spring MVC的其中一种方式而已

Spring Boot可以添加很多依赖,借助这些依赖实现不同的功能。Spring Boot通过添加Spring Web MVC框架,来实现web功能

比如:厨房可以用来做饭,但真实实现做饭功能的是火以及各种做饭相关的食材和工具

厨房就好比是Spring Boot,厨房可以装柜子,实现收纳功能,装燃气灶等,实现做饭功能

做饭这个事,就是MVC,在几千年前,有火有食材就可以实现做饭

不过Spring在实现MVC时,也结合自身项目的特点,做了一些改变,相对而言,下面这个图或许更加合适一些

不过,核心没变

比如上面的例子中,去饭店吃饭。一些饭店是前厅来负责接待客户,帮助客户点餐,也就是Controller来负责接收用户的请求

学习Spring MVC

既然Spring MVC是Web框架,那么当用户在浏览器中输入了url之后,我们的Spring MVC项目就可以感知到用户的请求,并给予响应

我们学习Spring MVC,重点也就是学习如何通过浏览器和用户程序进行交互

主要分为以下三个方面:

1.建立连接:将用户(浏览器)和Java程序连接起来,也就是访问一个地址能够调用到我们的Spring程序

2.请求:用户请求的时候会带一些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能

3.响应:执行了业务逻辑之后,要把程序执行的结果返回给用户,也就是响应

比如用户去银行存款:

1.建立连接:去柜台

2.请求:带着银行卡,身份证去存款

3.响应:银行返回一张存折

对于Spring MVC来说,掌握了以上3个功能就相当于掌握了Spring MVC

项目准备

Spring MVC项目创建和Spring Boot创建项目相同,在创建的时候选择Spring Web就相当于创建了Spring MVC的项目

Spring MVC使用Spring Boot的方式创建

Spring MVC更早期的实现方式,本文中不再讲解。

创建项目时,勾选上Spring Web模块即可,如下图所示:

建立连接

在Spring MVC中使用@RequestMapping来实现URL路由映射,也就是浏览器连接程序的作用

我们先来看看代码怎么写

创建一个UserController类,实现用户通过浏览器和程序的交互,具体实现代码如下:

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@RestController
public class UserController{
    //路由器规则注册
    @RequestMapping("/sayHi")
    public String sayHi(){
        return "hello,Spring MVC";
    }
}

注意:这里方法名和路径名称无需一致

接下来浏览器访问:http://127.0.0.1:8080/sayHi ,就可以看到程序返回的数据了

@RequestMapping 注解介绍

@RequestMapping是Spring Web MVC应用程序中最常被用到的注解之一,它是用来注册接口路由映射的

表示服务收到请求时,路径为 /sayHi 的请求就会调用 sayHi这个方法的代码

即:用户通过浏览器向服务器发送请求,URL为http://127.0.0.1:8080/sayHi,这时就会调用接口sayHi这个方法的代码

路由映射:当用户访问URL时,将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射

既然@RequestMapping已经可以达到我们的目的了,我们为什么还要加@RestController呢?

如果我们把@RestController去掉,再来访问一次,得到的响应如下:

可以看到,程序报了404,找不到该页面

这就是@RestController起到的作用

一个项目中,会有很多类,每个类可能有很多的方法,Spring程序怎么知道要执行哪个方法呢?

Spring会对所有的类进行扫描,如果类加了注解@RestController,Spring才会去看这个类里面的方法有没有加@RequestMapping这个注解,当然@RestController的作用不止这一点,咱们先用,后面再详细讲解

@RequestMapping使用

@RequstMapping既可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类路径+方法路径

@RequestMapping标识一个类:设置映射请求的请求路径的初始信息

@RequestMapping标识一个方法:设置映射请求的请求路径的具体信息

java 复制代码
@RequestMapping("/user")
@RestController
public class UserController {

    @RequestMapping("/sayHi")
    public String sayHi(){
        return "hello,Spring MVC";
	}
}

访问地址:http://127.0.0.1:8080/user/sayHi

注意

@RequestMapping的URL路径最前面加不加斜杠(/)都可以,Spring程序启动时,会进行判断,如果前面没有加斜杠,Spring会拼接上一个斜杠

java 复制代码
@RequestMapping("user")
@RestController
public class UserController {

    @RequestMapping("sayHi")
    public String sayHi(){
        return "hello,Spring MVC";
	}
}

访问http://127.0.0.1:8080/user/sayHi,依然可以正确响应

通常情况下,我们会主动加斜杠

@RequestMapping的URL路径也可以是多层路径,最终访问时,依然是 类路径+方法路径

java 复制代码
@RequestMapping("/user/m1")
@RestController
public class UserController {

    @RequestMapping("/say/hi")
    public String sayHi(){
        return "hello,Spring MVC";
	}
}

访问 http://127.0.0.1:8080/user/m1/say/hi

我们学习了HTTP协议后,知道GET/POST是常见的方法,那@RequestMapping到底是GET还是POST请求呢?

@RequestMapping是GET还是POST请求?

我们来测试一下就知道结论了

GET请求:

浏览器发送的请求类型是get,通过以上案例,可以看出来@RequestMapping支持get请求

POST请求:

我们通过form表单来构造请求:

创建test.html,html代码如下:

XML 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/user/sayHi" method="post">
        <input type="submit" value="提交">
    </form>
</body>
</html>

然后我们把前端代码放在static目录下,访问方式为:http://127.0.0.1:8080/test.html

如果有多层目录,访问链接从static目录开始写

如上图,访问链接为:http://127.0.0.1:8080/html/test.html

从运行结果可以看出:@RequestMapping既支持Get请求,又支持Post请求。同理,也支持其他的请求方式

那如何指定GET或者POST类型呢?

指定GET/POST方法类型

我们可以显示的指定@RequestMapping来接收POST的情况,如下所示:

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;

@RestController
public class UserController {
    @RequestMapping(value = "/getRequest",method= RequestMethod.POST) 
    public String sayHi(){
        return "get request...";
    }
}

Postman介绍

从上面的案例中,我们也发现了一个新的问题,就是我们测试后端方法时,还需要去写前端代码。这对我们来说,是一件麻烦又痛苦的事情

可能有人会说:"前面直接通过浏览器访问方法接口,不也得到了响应结果,以供测试

解释一下:

在Spring Web项目开发中,虽然直接通过浏览器访问方法接口路径可以快速验证部分基础功能,但这种测试方式存在显著局限性。

这里,我们只讲解,为什么需要结合前端代码进行的测试的部分原因:

1.请求参数验证的完整性

·浏览器地址栏只能传递简单的GET参数,无法模拟POST/PUT/DELETE请求体

·复杂对象参数需要JSON格式传递(需设置Content-Type:application/json)

·文件上传等multipart/form-data请求无法通过URL直接构造

2.HTTP方法验证

3.响应格式验证

4.状态码验证

...............

随着互联网的发展,也随着项目难度的增加,企业也按照开发的功能,把人员拆分成了不同的团队。界面显示交给"前端开发工程师",业务逻辑的实现交给"后端开发工程师"。

后端开发工程师,不要求也不需要掌握前端技能了

那后端开发工程师,如何测试自己的程序呢?--使用专业的接口测试工具

这里,我们介绍的是Postman,接下来我们学习如何使用Postman

Postman-CSDN博客

请求

访问不同的路径,就是发送不同的请求。在发送请求时,可能会带一些参数,所以学习Spring的请求,主要是学习如何传递参数到后端以及后端如何接收

传递参数,咱们主要是使用浏览器和Postman来模拟

后端开发人员无需过渡关注如何传递参数,了解即可,实际开发中以Postman测试为主

比如餐厅的厨师,不关注用户是在店里下单,还是外卖平台下单,或者小程序下单,只需要知道如何接收订单,根据订单做出对应的菜肴即可

传递单个参数

接收单个参数,在Spring MVC中直接用方法中的参数就可以,比如以下代码:

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

@RestController 
@RequestMapping("/param") 
public class ParamController {
    @RequestMapping("/m1")
    public String method1(String name){ 
        return "接收到参数name:"+ name;
    }
}

浏览器发送请求并传参

用浏览器访问http://127.0.0.1:8080/param/m1?name=spring

响应结果

根据响应结果,可以看到,后端程序正确拿到了name参数的值

Spring MVC会根据方法的参数名,找到对应的参数,赋值给方法

如果参数不一致,是获取不到参数的

比如请求URL:http://127.0.0.1:8080/param/m1?name1=spring

响应结果

注意事项

使用基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误

类型不匹配时,会报400操作

示例

java 复制代码
@RequestMapping("/m1/int")
public Object method1GetInt(int age){
    return "接收到参数age:" + age;
}

1.正常传递参数

浏览器访问:http://127.0.0.1:8080/param/m1/int?age=18

浏览器响应结果

通过Fiddler观察请求和响应,HTTP响应状态码为200,Content-Type为text/html

2.不传递age参数

浏览器访问:http://127.0.0.1:8080/param/m1/int

浏览器响应结果

通过Fiddler观察请求和响应,HTTP响应状态码为500

尝试观察程序的错误日志,并解决

一般看日志堆栈信息的首行,报错信息显示:

int类型的参数 'age',虽然是可选的,但由于被声明为基本类型而不能转换为空值(null)。考虑将其声明为对应基本类型的包装类型

按照错误信息解决错误即可

最开始学习时,会遇到各种各样的问题,我们要养成看错误日志的习惯,根据错误日志来解决问题

最开始可能会看不懂,或者比较懵,要耐下心来,慢慢看,后续会告诉大家更多看日志的思路

3.传递参数类型不匹配

浏览器访问:http://127.0.0.1:8080/param/m1/int?age=abc

浏览器响应结果

通过Fiddler观察请求和响应,HTTP响应状态码为400

对于包装类型,如果不传对应参数,Spring接收到的数据则为null

所以企业开发中,对应参数可能为空的数据,建议使用包装类型

传递多个参数

后端如何接收到多个参数呢?

和接收单个参数一样,直接使用方法的参数接收即可。使用多个形参

java 复制代码
@RequestMapping("/m2")
public Object method2(String name, String password){
    return "接收到参数name:" + name + ", password:" + password;
}

浏览器访问:http://127.0.0.1:8080/param/m2?name=zhangsan\&password=123456

响应结果为:

可以看到,后端程序正确拿到了name和password参数的值

当你有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置是不影响后端获取参数的结果

比如访问:http://127.0.0.1:8080/param/m2?password=123456\&name=zhangsan 同样可以拿到正确的结果

传递对象

如果参数比较多时,方法声明就需要有很多形参。并且后续每次新增一个参数,也需要修改方法声明。我们不妨把这些参数封装为一个对象

Spring MVC也可以自动实现对象参数的赋值,比如Person对象:

java 复制代码
public class Person {
    private int id;
    private String name;
    private String password;

    public int getId() { 
        return id;
    }
    public void setId(int id) { 
        this.id = id;
    }
    public String getName() { 
        return name;
    }
    public void setName(String name) { 
        this.name = name;
    }
    public String getPassword() { 
        return password;
    }
    public void setPassword(String password) { 
        this.password = password;
    }

    @Override
    public String toString() { 
        return "Person{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", password='" + password + '\'' + '}';
    }
}

传递对象代码实现:

java 复制代码
@RequestMapping("/m3")
public Object method3(Person p){
    return p.toString();
}

使用浏览器发送请求并传参:

http://127.0.0.1:8080/param/m3?id=5\&name=zhangsan\&password=123456

可以看到,后端程序正确拿到了Person对象里各个属性的值

Spring会根据参数名称自动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初始值,比如int类型的属性,会被赋值为0)

注意:

如果我们上述参数id、name、password并没有写get、set方法,最终后端程序无法得到前端输入的值,就无法给后端对象赋值。

可能有的人就会想,那我每次传递对象,还需要把各个参数个get、set方法给写出来,这不是很麻烦吗?

其实这样确实有些麻烦,可以在类上加注解@Data,这一注解便可以替代所有的get、set方法

后端参数重命名(后端参数映射)

某些特殊的情况下,前端传递的参数key后我们后端接收的key可以不一致,比如前端传递了一个time给后端,而后端是使用createtime字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使用 @RequestParam 来重命名前后端的参数值

具体示例如下,后端实现代码:

java 复制代码
@RequestMapping("/m4")
public Object method_4(@RequestParam("time") String createtime) {
    return "接收到参数createtime:" + createtime;
}

使用浏览器发送请求并传参:http://127.0.0.1:8080/param/m4?time=2023-09-12

浏览器响应结果:

可以看到,Spring可以正确的把浏览器传递的参数time绑定到后端参数createtime参数上

此时,如果浏览器使用createtime进行参数传递呢?

继续使用浏览器发送请求并传参:http://127.0.0.1:8080/param/m4?createtime=2023-09-12

浏览器响应结果:

错误日志信息 为:

控制台打印日志显示:请求参数【time】不存在

如果我们不传递参数【time】的话,会得到以下响应

可以得出结论:

1.使用@RequestParam进行参数重命名时,请求参数只能和@RequestParam声明的名称一致,才能进行参数绑定和赋值

2.使用@RequestParam进行参数重命名时,参数就变成了必传参数

非必传参数设置

如果我们的实际业务前端的参数是一个非必传的参数,针对上述问题,如何解决呢?

先来了解下参数必传的原因,我们查看@RequestParam注解的实现细节就可以发现端倪,注解实现如下:

java 复制代码
@Target({ElementType.PARAMETER}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented
public @interface RequestParam { 
    @AliasFor("name")
    String value() default "";

    @AliasFor("value") 
    String name() default "";

    boolean required() default true;

    String defaultValue() default  "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";

可以看到【required】的默认值为true,表示含义就是:该注解修饰的参数默认为必传

既然如此,我们可以通过设置@RequestParam中的【required=false】来避免不传递时报错,具体实现代码如下:

java 复制代码
@RequestMapping("/m4")
public Object method4(@RequestParam(value = "time", required = false) String createtime) {
    return "接收到参数createtime:" + createtime;
}

可以看到,添加【required=false】之后,time前面也加了key,变成了【value="time"】

注解属性赋值时,没有指明key的话,默认为value属性

如果需要有多个属性进行赋值时,需要写上key

浏览器访问:http://127.0.0.1:8080/param/m4

浏览器响应结果:

传递数组

Spring MVC可以自动绑定数组参数的赋值

后端实现代码:

java 复制代码
@RequestMapping("/m5")
public String method5(String[] arrayParam) {
    return Arrays.toString(arrayParam);
}

使用浏览器发送请求并传参:

数组参数:请求参数名与形参数组名称相同且请求参数为多个,后端定义数组类型形参即可接收参数

浏览器可以使用以下几种URL来发送请求:

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan\&arrayParam=lisi\&arrayParam=wangwu..

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan%2Clisi%2Cwangwu..

解释:【%2c】是逗号的转义编码,解码后的url即为下面所示

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan,lisi,wangwu..(我们使用这个)

浏览器响应结果:

可以看到后端对数组参数进行了正确的接收和响应

或者使用Postman来发送请求

传递集合

集合参数:和数组类似,同一个请求参数名有多个,且需要使用@RequestParam绑定参数关系

默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使用@RequestParam绑定参数关系

后端接收代码:

java 复制代码
@RequestMapping("/m6")
public String method6(@RequestParam List<String> listParam){
    return "size:"+listParam.size() + ",listParam:"+listParam;
}

请求方式和数组类似:

浏览器传参:

方式一:http://127.0.0.1:8080/param/m6?listParam=zhangsan\&listParam=lisi\&listParam=wangwu

方式二:http://127.0.0.1:8080/param/m6?listParam=zhangsan%2Clisi%2Cwangwu

Postman传参测试:

传递JSON数据

JSON概念

JSON:JavaScript Object Notation 【JavaScript对象表示法】

JSON是一种轻量级的数据交互格式。它基于ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据

简单来说:JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串。主要负责在不同的语言中数据传递和交换

JSON与JavaScript的关系

两者其实没有关系,只是语法相似,js开发者能更快的上手而已,但是它的语法本身比较简单,所以也很好学

JSON语法

JSON是一个字符串,其格式非常类似于JavaScript对象字面量的格式

我们先来看一段JSON数据

javascript 复制代码
{
    "squadName": "Super hero squad",
    "homeTown": "Metro City",
    "formed": 2016,
    "secretBase": "Super tower",
    "active": true,
    "members": [{
            "name": "Molecule Man",
            "age": 29,
            "secretIdentity": "Dan Jukes",
            "powers": ["Radiation resistance", "Turning tiny", "Radiation
blast"]
	},	{	
			"name": "Madame Uppercut",
			"age": 39,
			"secretIdentity": "Jane Wilson",
			"powers": ["Million tonne punch", "Damage resistance", "Superhuman
	reflexes"]
    }, {	
		    "name": "Eternal Flame",
		    "age": 1000000,
		    "secretIdentity": "Unknown",
		    "powers": ["Immortality", "Heat Immunity", "Inferno",
"Teleportation", "Interdimensional travel"]
	}]
 }

也可以压缩表示:

javascript 复制代码
{"squadName":"Super hero squad","homeTown":"Metro City","formed":2016,"secretBase":"Super tower","active":true,"members": [{"name":"Molecule Man","age":29,"secretIdentity":"Dan Jukes","powers": ["Radiation resistance","Turning tiny","Radiation blast"]},{"name":"Madame Uppercut","age":39,"secretIdentity":"Jane Wilson","powers":["Million tonne punch","Damage resistance","Superhuman reflexes"]},{"name":"EternalFlame","age":1000000,"secretIdentity":"Unknown","powers":["Immortality","Heat Immunity","Inferno","Teleportation","Interdimensional travel"]}]}

和上面描述的数据一样,只不过上面的进行了格式化,更易读

JSON的语法:

1.数据在【键值对(key/Value)】中

2.数据由逗号【,】分隔

3.对象用【{ }】表示

4.数组用【 [ ] 】表示

5.值可以为对象,也可以为数组,数组中可以包含多个对象

JSON的两种结构

1.对象:大括号{ } 保存的对象是一个无序的键值对集合。一个对象以左括号 { 开始,右括号 } 结束。每个"键"后跟一个冒号 : ,键值对使用逗号 , 分隔

2.数组:中括号[ ] 保存的数组是值(value)的有序集合。一个数组以左中括号 [ 开始,右中括号 ] 结束,值之间使用逗号 , 分隔

所以,以下都是合法的JSON数据

javascript 复制代码
{"name":"admin","age":18}
["hello",3.1415,"json"]
[{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age":20}]

也可以使用在线JSON格式化工具来进行校验和书写:在线JSON校验格式化工具(Be JSON)

JSON字符串和Java对象互转

JSON本质上是一个字符串,通过文本来存储和描述数据

Spring MVC框架也集成了JSON的转换工具,我们可以直接使用,来完成JSON字符串和Java对象的互转

本质上是jackson-databind提供的功能,Spring MVC框架中已经把该工具包引入了进来,咱们直接使用即可,如果脱离Spring MVC使用,需要引入相关依赖

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

JSON的转换工具包有很多,jackson-databind只是其中的一种

比如:使用ObjectMapper对象提供的两个方法,可以完成对象和JSON字符串的互转

示例:

java 复制代码
public class JSONUtils {
    private static ObjectMapper objectMapper = new ObjectMapper(); 

    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person();
        person.setId(5);
        person.setName("zhangsan");
        person.setPassword("123456");
        //对象转为JSON字符串
        String jsonStr = objectMapper.writeValueAsString(person);
        System.out.println("JSON字符串为:"+jsonStr);
        //JSON字符串转为对象
        Person p = objectMapper.readValue(jsonStr,Person.class);
        System.out.println("转换的对象
        id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
	}
}

writeValueAsString:把对象转为JSON字符串

readValue:把字符串转为对象

JSON优点

1.简单易用:语法简单,易于理解和编写,可以快速地进行数据交换

2.跨平台支持:JSON可以被多种编程语言解析和生成,可以在不同的平台和语言之间进行数据交换和传输

3.轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占用带宽较小,可以提高数据传输速度

4.易于扩展:JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,编译扩展和使用

5.安全性:JSON数据格式是一种纯文本格式,不包含可执行代码,不会执行恶意代码,因此具有较高的安全性

基于以上特点,JSON在Web应用程序中被广泛使用,如前后端数据交互、API接口数据传输等

传递JSON对象

接收JSON对象,需要使用@RequestBody注解

RequestBody:请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须写在请求正文中

后端实现:

java 复制代码
@RequestMapping(value = "/m7")
public Object method7(@RequestBody Person person) {
    return person.toString();
}

使用Postman来发送JSON请求参数:

根据响应结果可以看到,后端正确接受了

通过Fiddler观察一下请求参数:

尝试去除掉@RequestBody看看有何区别

java 复制代码
@RequestMapping(value = "/m7")
public Object method7(Person person) {
    return person.toString();
}

请求响应结果如下:

后端未能成功给Person对象赋值

相关推荐
加班是不可能的,除非双倍日工资11 分钟前
css预编译器实现星空背景图
前端·css·vue3
IT毕设实战小研22 分钟前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi1 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip1 小时前
vite和webpack打包结构控制
前端·javascript
excel1 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
甄超锋1 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国2 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼2 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy2 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT2 小时前
promise & async await总结
前端