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
    • 获取数组里指定索引的元素:数组[索引]

这里需要牢牢记住对应的格式:

对象:

K-V的形式

{"属性1":"属性1的值","属性2":"属性2的值","属性3":"属性3的值","属性4":"属性4的值"}

数组:

数组中每一个都是一个对象

[{},{},{}]

混合类型:

最终都是由数组和对象组合而成的。

3、转换工具类

这里主要是用来介绍转换工具Fastjson,用来转换Java对象和json格式

首先介绍一下这里的API

fastjson提供了核心类:JSONJSON提供了一些常用的静态方法:

方法 说明
toJSONString(Object obj) 把obj对象里的数据转换成json格式
parseObject(String json, Class type) 把json字符串,还原成type类型的Java对象
parseObject(String json, TypeReference reference) 把json字符串,还原成带泛型的复杂Java对象
  • 其中TypeReferencecom.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;

如果属性中有,那么就进行赋值操作;

posted @ 2021-10-28 22:58  写的代码很烂  阅读(139)  评论(0编辑  收藏  举报