走进Java接口测试之fastjson指南

2021年09月15日 阅读数:1
这篇文章主要向大家介绍走进Java接口测试之fastjson指南,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

引言

在上文 走进Java接口测试之理解JSON和XML基础 咱们介绍了 JSON 的基础知识,本文咱们深刻研究阿里巴巴的开源 JSON 解析库 fastjson。git

什么是fastjson?

fastjson 是阿里巴巴的开源 JSON 解析库,它能够解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也能够从 JSON 字符串反序列化到JavaBean。github

截止2019/2/1:json

  • Github Stars: 16434服务器

  • Github Forks: 4661框架

GitHub:https://github.com/alibaba/fastjson/ide

fastjson的特色

速度快

fastjson 相对其余 JSON 库的特色是快,从 2011 年 fastjson 发布1.1.x版本以后,其性能从未被其余 Java 实现的 JSON 库超越。函数

使用普遍

fastjson 在阿里巴巴大规模使用,在数万台服务器上部署,fastjson 在业界被普遍接受。在 2012 年被开源中国评选为最受欢迎的国产开源软件之一。工具

测试完备

fastjson 有很是多的 testcase,在1.2.11版本中,testcase 超过3321个。每次发布都会进行回归测试,保证质量稳定。性能

使用简单

fastjson 的 API 十分简洁。测试

  1. String text = JSON.toJSONString(obj); //序列化

  2. VO vo = JSON.parseObject("{...}", VO.class); //反序列化

功能完备

支持泛型,支持流处理超大文本,支持枚举,支持序列化和反序列化扩展。

fastjson使用

Maven配置

为了开始使用FastJson,咱们首先须要将它添加到咱们的 pom.xml

  1.  <!--引入效率插件-->

  2.        <dependency>

  3.            <groupId>org.projectlombok</groupId>

  4.            <artifactId>lombok</artifactId>

  5.            <optional>true</optional>

  6.        </dependency>

  7.        <!--引入FastJson包-->

  8.        <dependency>

  9.            <groupId>com.alibaba</groupId>

  10.            <artifactId>fastjson</artifactId>

  11.            <version>1.2.47</version>

  12.        </dependency>

  13.        <!--引入testng测试框架-->

  14.        <dependency>

  15.            <groupId>org.testng</groupId>

  16.            <artifactId>testng</artifactId>

  17.            <version>6.14.3</version>

  18.        </dependency>

将Java对象转换为JSON格式

让咱们定义如下Person Java bean

  1. @Data

  2. @Builder

  3. @NoArgsConstructor

  4. @AllArgsConstructor

  5. public class Person {

  6.  

  7.       @JSONField(name = "AGE")

  8.    private int age;

  9.  

  10.    @JSONField(name = "FULL NAME")

  11.    private String fullName;

  12.  

  13.    @JSONField(name = "DATE OF BIRTH")

  14.    private Date dateOfBirth;

  15. }

咱们可使用 JSON.toJSONString() 将 Java 对象转换为 JSON 字符串

  1. private List<Person> listOfPersons;

  2.  

  3.    @BeforeTest

  4.    public void setUp() {

  5.        listOfPersons = new ArrayList<Person>();

  6.        // 获取当前时间,取得一个Calendar的实例

  7.        Calendar calendar = Calendar.getInstance();

  8.        // 设置日历

  9.        calendar.set(2019, 01, 31);

  10.        // 实例化Java对象

  11.        listOfPersons.add(new Person(15, "John Doe", calendar.getTime()));

  12.        listOfPersons.add(new Person(20, "Janette Doe", calendar.getTime()));

  13.    }

  14.  

  15.    @Test(description = "将Java对象转换为JSON格式")

  16.    public void whenJavaList_thanConvertToJsonCorrect() {

  17.  

  18.        // 将Java对象转换为JSON字符串

  19.        String personJsonFormat = JSON.toJSONString(listOfPersons);

  20. }

这是结果:

  1. [  

  2.    {  

  3.        "AGE":15,

  4.        "DATE OF BIRTH":1468962431394,

  5.        "FULL NAME":"John Doe"

  6.    },

  7.    {  

  8.        "AGE":20,

  9.        "DATE OF BIRTH":1468962431394,

  10.        "FULL NAME":"Janette Doe"

  11.    }

  12. ]

咱们还能够进一步开始自定义输出并控制排序,日期格式或序列化标志等内容。 例如 - 让咱们更新 bean 并添加几个字段:

  1. @Data

  2. @Builder

  3. @NoArgsConstructor

  4. @AllArgsConstructor

  5. public class Person {

  6.  

  7.    // 忽略序列化和反序列化

  8.    @JSONField(name = "AGE", serialize = false, deserialize = false)

  9.    private int age;

  10.  

  11.    // ordinal指定顺序

  12.    @JSONField(name = "LAST NAME", ordinal = 2)

  13.    private String lastName;

  14.  

  15.    @JSONField(name = "FIRST NAME", ordinal = 1)

  16.    private String firstName;

  17.  

  18.    // format格式化

  19.    @JSONField(name = "DATE OF BIRTH", format = "dd/MM/yyyy",ordinal = 3)

  20.    private Date dateOfBirth;

  21.  

  22. }

如下是咱们能够与 @JSONField 注解一块儿使用的最基本参数列表,以便自定义转换过程:

  • 参数格 format 用于正确格式化日期属性

  • 默认状况下,fastjson 库彻底序列化Java bean,但咱们可使用参数 -serialize来忽略特定字段的序列化

  • 参数 ordinal 用于指定字段顺序

这是新的输出:

  1. [

  2.    {

  3.        "FIRST NAME":"Doe",

  4.        "LAST NAME":"Jhon",

  5.        "DATE OF BIRTH":"31/01/2019"

  6.    },

  7.    {

  8.        "FIRST NAME":"Doe",

  9.        "LAST NAME":"Janette",

  10.        "DATE OF BIRTH":"31/01/2019"

  11.    }

  12. ]

fastjson 还支持很是有趣的 BeanToArray 序列化功能:

  1. String jsonOutput= JSON.toJSONString(listOfPersons, SerializerFeature.BeanToArray);

这是在这种状况下输出的样子:

  1. [

  2.    [

  3.        15,

  4.        1469003271063,

  5.        "John Doe"

  6.    ],

  7.    [

  8.        20,

  9.        1469003271063,

  10.        "Janette Doe"

  11.    ]

  12. ]

完整示例:

  1. private List<Person> listOfPersons;

  2.  

  3.    @BeforeTest

  4.    public void setUp() {

  5.        listOfPersons = new ArrayList<Person>();

  6.        // 获取当前时间,取得一个Calendar的实例

  7.        Calendar calendar = Calendar.getInstance();

  8.        // 设置日历

  9.        calendar.set(2019, 01, 31);

  10.        // 实例化Java对象

  11.        listOfPersons.add(new Person(15, "John", "Doe", calendar.getTime()));

  12.        listOfPersons.add(new Person(20, "Janette", "Doe", calendar.getTime()));

  13.    }

  14.  

  15.    @Test(description = "将Java对象转换为JSON格式")

  16.    public void whenJavaList_thanConvertToJsonCorrect() {

  17.  

  18.        // 将Java对象转换为JSON字符串

  19.        String personJsonFormat = JSON.toJSONString(listOfPersons);

  20.        // 断言字符串是否相同

  21.        Assert.assertEquals(personJsonFormat, "[{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"John\",\"DATE OF BIRTH\":"

  22.                + "\"01/02/2019\"},{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"Janette\",\"DATE OF BIRTH\":"

  23.                + "\"01/02/2019\"}]");

  24.    }

建立JSON对象

与其余 JSON 库同样,从头开始建立 JSON 对象很是简单,只须要组合JSONObject 和 JSONArray 对象:

  1. @Test(description = "建立JSON对象")

  2.    public void whenGenerateJson_thanGenerationCorrect() {

  3.        // 组合JSONObject和JSONArray对象

  4.        JSONArray jsonArray = new JSONArray();

  5.        for (int i = 0; i < 2; i++) {

  6.            JSONObject jsonObject = new JSONObject();

  7.            jsonObject.put("FIRST NAME", "John" + i);

  8.            jsonObject.put("LAST NAME", "Doe" + i);

  9.            jsonObject.put("DATE OF BIRTH", "2019/2/1 12:12:12");

  10.            jsonArray.add(jsonObject);

  11.        }

  12.  

  13.        Assert.assertEquals(jsonArray.toString(), "[{\"LAST NAME\":\"Doe0\",\"DATE OF BIRTH\":"

  14.                + "\"2019/2/1 12:12:12\",\"FIRST NAME\":\"John0\"},{\"LAST NAME\":\"Doe1\","

  15.                + "\"DATE OF BIRTH\":\"2019/2/1 12:12:12\",\"FIRST NAME\":\"John1\"}]");

  16.        System.out.println(jsonArray.toString());

  17.    }

如下是输出结果:

  1. [

  2.   {

  3.      "LAST NAME":"Doe0",

  4.      "DATE OF BIRTH":"2019/2/1 12:12:12",

  5.      "FIRST NAME":"John0"

  6.   },

  7.   {

  8.      "LAST NAME":"Doe1",

  9.      "DATE OF BIRTH":"2019/2/1 12:12:12",

  10.      "FIRST NAME":"John1"

  11.   }

  12. ]

将JSON字符串解析为Java对象

如今咱们知道如何从头开始建立 JSON 对象,以及如何将 Java 对象转换为它们的 JSON 格式,让咱们把重点放在如何解析 JSON 格式上:

  1. @Test(description = "将JSON字符串解析为Java对象")

  2.    public void whenJson_thanConvertToObjectCorrect() {

  3.        // 将Java对象转换为JSON字符串

  4.        String personJsonFormat = JSON.toJSONString(listOfPersons.get(0));

  5.        System.out.println(personJsonFormat);

  6.  

  7.        // 从JSON字符串中获取Java对象

  8.        Person newPerson = JSON.parseObject(personJsonFormat, Person.class);

  9.        System.out.println(newPerson.toString());

  10.  

  11.        // 使用参数serialize忽略Age字段的序列化

  12.        Assert.assertEquals(newPerson.getAge(), 0);

  13.        System.out.println(newPerson.getAge());

  14.  

  15.        Assert.assertEquals(newPerson.getFirstName(), listOfPersons.get(0).getFirstName());

  16.        System.out.println(newPerson.getFirstName());

  17.  

  18.        Assert.assertEquals(newPerson.getLastName(), listOfPersons.get(0).getLastName());

  19.        System.out.println(newPerson.getLastName());

  20.    }

咱们可使用 JSON.parseObject() 从 JSON 字符串中获取 Java 对象。 请注意,若是已经声明了本身的参数化构造函数,则必须定义 no-args 或默认构造函数,不然将抛出 com.alibaba.fastjson.JSONException

这是新建立的对象。

  1. Person(age=0, lastName=John, firstName=Doe, dateOfBirth=Sun JAN 31 00:00:00 CST 2019)

使用ContextValueFilter配置JSON转换

在某些状况下,咱们可能须要更多地控制从 Java 对象到 JSON 格式的转换过程。 在这种状况下,咱们可使用 ContextValueFilter 对象对转换流应用其余过滤和自定义处理:

  1. @Test(description = "使用ContextValueFilter配置JSON转换")

  2.    public void givenContextFilter_whenJavaObject_thanJsonCorrect() {

  3.        // 使用ContextValueFilter对象对转换流应用其余过滤和自定义处理

  4.        ContextValueFilter valueFilter = new ContextValueFilter() {

  5.            public Object process(BeanContext context, Object object, String name, Object value) {

  6.                // 隐藏了 DATE OF BIRTH 字段,强制一个常量值

  7.                if (name.equals("DATE OF BIRTH")) {

  8.                    return "NOT TO DISCLOSE";

  9.                }

  10.                // 忽略了全部不是John或Doe的字段

  11.                if (value.equals("John") || value.equals("Doe")) {

  12.                    return ((String) value).toUpperCase();

  13.                } else {

  14.                    return null;

  15.                }

  16.            }

  17.        };

  18.        // 将Java对象转换为JSON字符串并过滤及自定义处理

  19.        String personJsonFormat = JSON.toJSONString(listOfPersons, valueFilter);

  20.        System.out.println(personJsonFormat);

  21.  

  22.    }

在这个例子中,咱们隐藏了 DATE OF BIRTH 字段,经过强制一个常量值,咱们也忽略了全部不是 John 或 Doe 的字段:

  1. [

  2.   {

  3.      "FIRST NAME":"DOE",

  4.      "LAST NAME":"JOHN",

  5.      "DATE OF BIRTH":"NOT TO DISCLOSE"

  6.   },

  7.   {

  8.      "FIRST NAME":"DOE",

  9.      "DATE OF BIRTH":"NOT TO DISCLOSE"

  10.   }

  11. ]

正如你所看到的,这是一个很是基本的示例,固然能够在更复杂的测试场景中使用相同的概念 - 结合 fastjson 在实际项目中提供的这些功能强大且轻量级的工具集。

使用NameFilter和SerializeConfig

fastjson 提供了一组工具来在处理任意对象时自定义 JSON 操做 - 咱们没有源码的对象。

让咱们假设咱们有一个最初在本文中声明的 Person Java bean 的编译版本,咱们须要对字段命名和基本格式进行一些加强:

  1.    @Test(description = "使用NameFilter和SerializeConfig")

  2.    public void givenSerializeConfig_whenJavaObject_thanJsonCorrect() {

  3.  

  4.        // formatName过滤器来处理字段名称。

  5.        NameFilter formatName = new NameFilter() {

  6.            public String process(Object object, String name, Object value) {

  7.                return name.toLowerCase().replace(" ", "_");

  8.            }

  9.        };

  10.        SerializeConfig.getGlobalInstance().addFilter(Person.class, formatName);

  11.  

  12.        // 将对象转换为JSON格式,快速在日期字段上应用相同的格式规则。

  13.        String jsonOutput = JSON.toJSONStringWithDateFormat(listOfPersons, "yyyy-MM-dd");

  14.  

  15.        System.out.println(jsonOutput);

  16.        Assert.assertEquals(jsonOutput, "[{\"first_name\":\"Doe\",\"last_name\":\"John\","

  17.                + "\"date_of_birth\":\"2019-02-01\"},{\"first_name\":\"Doe\",\"last_name\":"

  18.                + "\"Janette\",\"date_of_birth\":\"2019-02-01\"}]");

  19.  

  20.  

  21.        // 从新设置自定义序列化器

  22.        SerializeConfig.getGlobalInstance().put(Person.class, null);

  23.    }

咱们使用 NameFilter 匿名类声明了 formatName 过滤器来处理字段名称。新建立的过滤器与 Person 类相关联,而后添加到全局实例 - 它基本上是 SerializeConfig 类中的静态属性。 如今咱们能够轻松地将对象转换为 JSON 格式,如本文前面所示。

请注意,咱们使用了 toJSONStringWithDateFormat() 而不是 toJSONString() 来快速在日期字段上应用相同的格式规则。

这是输出:

  1. [

  2.   {

  3.      "first_name":"Doe",

  4.      "last_name":"John",

  5.      "date_of_birth":"2019-01-31"

  6.   },

  7.   {

  8.      "first_name":"Doe",

  9.      "last_name":"Janette",

  10.      "date_of_birth":"2019-01-31"

  11.   }

  12. ]

如你所见 - 字段名称已更改,日期值确实已正确格式化。 

将 SerializeFilter 与 ContextValueFilter 相结合能够彻底控制任意和复杂Java 对象的转换过程。

小结

在本文中,咱们展现了如何使用 fastjson 将Javabean 转换成 JSON 字符串,以及如何反过来。咱们还展现了如何使用 fastjson 的一些核心特性来定制 JSON 输出。 fastjson库提供了一个相对简单但仍然很是强大的API,JSON.toJSONString 和 JSON.parseObject 可知足大多数需求。

 

 

本文源码: 

https://github.com/7DGroup/Java-API-Test-Examples/tree/master/SpringBoot-fastjson-demo