mvc之json
JSON
1、简单介绍
查看json百度百科介绍:
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
我们可以理解JSON就是一个容易生成和解析的数据格式; 常用作客户端(前端,IOS,安卓)和服务器(JavaEE)之间的数据交换
2、语法介绍
- 定义方式:
- 对象形式:
{key:value,key:value...}
- key是字符串
- value是任意的合法数据类型
- 多个之间使用,隔开,最后一个,不写
- key和value之间使用:连接
- 数组形式:
[element1, element2, ...]
- 混合(嵌套)形式:以上两种类型任意混合
- json对象的value,可以是任意类型,当然也可以是数组
- 数组里的element,可以是任意类型,当然也可以是json对象
- 对象形式:
- 解析语法:
- 获取json对象里的value值:
json对象.key
- 获取数组里指定索引的元素:
数组[索引]
- 获取json对象里的value值:
这里需要牢牢记住对应的格式:
对象:
K-V的形式
{"属性1":"属性1的值","属性2":"属性2的值","属性3":"属性3的值","属性4":"属性4的值"}
数组:
数组中每一个都是一个对象
[{},{},{}]
混合类型:
最终都是由数组和对象组合而成的。
3、转换工具类
这里主要是用来介绍转换工具Fastjson,用来转换Java对象和json格式
首先介绍一下这里的API
fastjson提供了核心类:JSON
,JSON
提供了一些常用的静态方法:
方法 | 说明 |
---|---|
toJSONString(Object obj) |
把obj对象里的数据转换成json格式 |
parseObject(String json, Class type) |
把json字符串,还原成type类型的Java对象 |
parseObject(String json, TypeReference reference) |
把json字符串,还原成带泛型的复杂Java对象 |
- 其中
TypeReference
:com.alibaba.fastjson.TypeReference
- 是一个抽象类,用于配置完整的泛型映射信息,避免泛型丢失的问题。用法示例:
// List<Integer> 类型的映射信息
TypeReference ref1 = new TypeReference<List<Integer>>() {};
// List<User> 类型的映射信息
TypeReference ref2 = new TypeReference<List<User>>() {};
// Map<String,User> 类型的映射信息
TypeReference ref3 = new TypeReference<Map<String,User>>(){};
3.1、将对象转换成json
首先创建一个类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
public class Animal {
private Integer id;
private String name;
private List<String> stringList;
}
下面来写测试代码:
DemoOne:
将对象转换成json
@Test
public void testOne(){
Animal animal = Animal.builder().id(1).name("animal").build();
String s = JSON.toJSONString(animal);
System.out.println(s);
}
查看控制台输出:
{"id":1,"name":"animal"}
DemoTwo:
将map转换成json
@Test
public void testTwo(){
Animal animal = Animal.builder().id(1).name("animal").build();
Map<String,Object> objectMap = new HashMap<>();
objectMap.put("hello","world");
objectMap.put("world",animal);
String s = JSON.toJSONString(objectMap);
System.out.println(s);
}
查看控制台输出:
{"world":{"id":1,"name":"animal"},"hello":"world"}
DemoThree:
将list转换成json
@Test
public void testThree(){
Animal animal1 = Animal.builder().id(1).name("animal1").build();
Animal animal2 = Animal.builder().id(2).name("animal2").build();
Animal animal3 = Animal.builder().id(3).name("animal3").build();
Animal animal4 = Animal.builder().id(4).name("animal4").build();
List<Animal> animalList = new ArrayList<>();
animalList.add(animal1);
animalList.add(animal2);
animalList.add(animal3);
animalList.add(animal4);
String s = JSON.toJSONString(animalList);
System.out.println(s);
}
查看控制台输出:
[{"id":1,"name":"animal1"},{"id":2,"name":"animal2"},{"id":3,"name":"animal3"},{"id":4,"name":"animal4"}]
3.2、将json转换成对象
利用上面产生的json格式数据来进行转换:
DemoOne:
将json转换成对象:
@Test
public void testFour(){
String json = "{\"id\":1,\"name\":\"animal\"}";
Animal animal = JSON.parseObject(json, Animal.class);
System.out.println(animal);
}
查看控制台输出:
Animal(id=1, name=animal, stringList=null)
从这里可以看到即使没有将里面的属性stringlist属性来进行转换,但是转换成对象之后,依然是有对应的值产生。
DemoTwo:
将json转换成map:
@Test
public void testFive(){
String json = "{\"world\":{\"id\":1,\"name\":\"animal\"},\"hello\":\"world\"}";
Map map = JSON.parseObject(json, Map.class);
System.out.println(map);
}
查看控制台输出:
{world={"name":"animal","id":1}, hello=world}
从这里可以看出来,这里的json转换成了map之后,K-V之间是K=V的情况
DemoThree:
将json转换成list:
@Test
public void testSix(){
String json = "[{\"id\":1,\"name\":\"animal1\"},{\"id\":2,\"name\":\"animal2\"},{\"id\":3,\"name\":\"animal3\"},{\"id\":4,\"name\":\"animal4\"}]";
List list = JSON.parseObject(json, List.class);
System.out.println(list);
}
查看控制台显示:
[{"name":"animal1","id":1}, {"name":"animal2","id":2}, {"name":"animal3","id":3}, {"name":"animal4","id":4}]
成功将其进行了转换。但是对于json转换成对象来说,我们通常更喜欢用TypeReference来进行操作。
下面来将上面的例子来进行演示一下:
将json转换成map:
@Test
public void testSeven(){
String json = "{\"world\":{\"id\":1,\"name\":\"animal\"},\"hello\":\"world\"}";
Map<String, Object> objectMap = JSON.parseObject(json, new TypeReference<Map<String, Object>>() {
});
System.out.println(objectMap);
}
查看控制台输出:
{world={"name":"animal","id":1}, hello=world}
将json转换成list:
@Test
public void testEight(){
String json = "[{\"id\":1,\"name\":\"animal1\"},{\"id\":2,\"name\":\"animal2\"},{\"id\":3,\"name\":\"animal3\"},{\"id\":4,\"name\":\"animal4\"}]";
List<Animal> animalList = JSON.parseObject(json, new TypeReference<List<Animal>>() {
});
System.out.println(animalList);
}
查看控制台输出:
[Animal(id=1, name=animal1, stringList=null), Animal(id=2, name=animal2, stringList=null), Animal(id=3, name=animal3, stringList=null), Animal(id=4, name=animal4, stringList=null)]
3.3、总结
将对象转换成json的时候,属性如果有值,那么在json中就有对应的显示;如果属性中没有对应的值,那么输出json的时候就不会有对应的显示;这里是一个重要的点。
对应的测试如下所示:
@Test
public void testNine(){
User user = new User();
String s = JSON.toJSONString(user);
System.out.println(s);
User user1 = JSON.parseObject(s, User.class);
System.out.println(user1);
User user2 = JSON.parseObject(s, new TypeReference<User>() {
});
System.out.println(user2);
}
控制台输出:
{}
User(name=null)
User(name=null)
4、子类和父类json转换
这是最近在做项目的时候发现的一个问题,所以在这里来记录一下。
创建两个类:
@Data
public class Person {
private Integer id;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
public class User extends Person {
private String name;
}
编写测试类:
@Test
void contextLoads() {
User user = User.builder().build();
Person person = user;
String s = JSON.toJSONString(person);
System.out.println(s);
}
查看控制台输出:
{}
那么继续测试:
@Test
void contextLoads() {
User user = User.builder().build();
Person person = user;
person.setId(11);
String s = JSON.toJSONString(person);
System.out.println(s);
}
输出结果:
{"id":11}
继续测试:
@Test
void contextLoads() {
User user = User.builder().build();
user.setName("guang");
Person person = user;
person.setId(11);
String s = JSON.toJSONString(person);
System.out.println(s);
}
输出结果:
{"id":11,"name":"guang"}
不难总结出来一个现象:
当子类中属性是有值的时候,使用父类来进行输出的时候,将父类引用转换成json的时候,也会将子类中的来进行转换;
当子类中属性为空的时候,使用父类来转换成为json的时候,父类也只会转换出来当前有的值;
综合对比,当子类中有值,就输出值;如果没有值,就转换出一个空的json出来。而没有对应的属性
5、SpringMVC中的转换
新建两个类,然后写两个测试:
@Data
public class Person {
private Integer id;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
public class User extends Person {
private String name;
}
测试类:
@PostMapping("/testPerson")
public String testPerson(@RequestBody Person person){
System.out.println(person);
return "success";
}
@PostMapping("/testUser")
public String testA(@RequestBody User user){
System.out.println(user);
return "success";
}
控制台结果:
User(name=guang)
Person(id=1)
从这里可以看到,这里的转换是哪个对象来进行接收的,能够进行匹配上的,就给对象的属性来进行赋值操作。
在这里来进行赋值,没有所谓的子父类继承的操作。单纯的来进行赋值操作而已。
那么再次新建一个包含了这两个属性的值:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
public class Animal {
private Integer id;
private String name;
private List<String> stringList;
}
再次来进行测试:
@PostMapping("/testUser")
public String testA(@RequestBody User user){
System.out.println(user);
return "success";
}
查看控制台输出:
Animal(id=1, name=guang, stringList=null)
属性值如果前端传输过来的没有这个属性的数据,那么接收回来的返回的就是null;
如果属性中有,那么就进行赋值操作;