Введение в Fastjson
Fastjson — это библиотека Java, которая может преобразовывать объекты Java в формат JSON, и, конечно, она также может преобразовывать строки JSON в объекты Java.
Fastjson может работать с любым объектом Java, даже с уже существующими объектами без исходного кода.
Адрес исходного кода Fastjson:https://github.com/alibaba/fastjson
Китайская вики Fastjson:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN
Возможности Fastjson
- Предоставляет инструменты синтаксического анализа как для серверной части, так и для Android-клиентов, с хорошей производительностью.
- Предоставляет методы toJSONString() и parseObject() для преобразования между объектами Java и JSON. Вызов метода toJSONString преобразует объект в строку JSON, тогда как метод parseObject выполняет обратное — преобразует строку JSON в объект.
- Позволяет преобразовывать уже существующие неизменяемые объекты (только класс, без исходного кода).
- Широкая поддержка обобщений Java.
- Позволяет задавать собственное представление объектов и пользовательские классы сериализации.
- Поддерживает сколь угодно сложные объекты (с глубокими иерархиями наследования и широким использованием обобщённых типов).

Загрузка и использование
Вы можете скачать его напрямую из Maven Central Repository:
https://repo1.maven.org/maven2/com/alibaba/fastjson/
Или настройте зависимость Maven:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>x.x.x</version>
</dependency>
гдеx.x.x— номер версии. Используйте конкретную версию по необходимости; рекомендуется последняя версия.
Преобразование объектов Java в формат JSON
Определите следующий Person JavaBean:
Пример
@JSONField(name = "AGE")
private int age;
@JSONField(name = "FULL NAME")
private String fullName;
@JSONField(name = "DATE OF BIRTH")
private Date dateOfBirth;
public Person(int age, String fullName, Date dateOfBirth) {
super();
this.age = age;
this.fullName= fullName;
this.dateOfBirth = dateOfBirth;
}
// стандартные геттеры & сеттеры
}
Вы можете использовать JSON.toJSONString() для преобразования объекта Java в объект JSON:
@Before
public void setUp() {
listOfPersons.add(new Person(15, "John Doe", new Date()));
listOfPersons.add(new Person(20, "Janette Doe", new Date()));
}
@Test
public void whenJavaList_thanConvertToJsonCorrect() {
String jsonOutput= JSON.toJSONString(listOfPersons);
}
Вывод:
[
{
"AGE":15,
"DATE OF BIRTH":1468962431394,
"FULL NAME":"John Doe"
},
{
"AGE":20,
"DATE OF BIRTH":1468962431394,
"FULL NAME":"Janette Doe"
}
]
Мы также можем настраивать вывод и управлять порядком полей, форматом отображения даты, флагами сериализации и т. д.
Далее давайте обновим бин и добавим несколько полей:
private int age;
@JSONField(name="LAST NAME", ordinal = 2)
private String lastName;
@JSONField(name="FIRST NAME", ordinal = 1)
private String firstName;
@JSONField(name="DATE OF BIRTH", format="dd/MM/yyyy", ordinal = 3)
private Date dateOfBirth;
В приведённом выше коде мы перечислили основные категории параметров и использовали аннотацию @JSONField для реализации пользовательского преобразования:
- format Параметр используется для форматированияdateсвойства.
- По умолчанию библиотека FastJson может сериализовать сущности Java bean, но мы можем использоватьserialize , чтобы указать поля, которые не должны сериализоваться.
- Используйтеordinal параметр, чтобы указать порядок полей.
Таким образом, приведённый выше вывод становится:
[
{
"FIRST NAME":"Doe",
"LAST NAME":"Jhon",
"DATE OF BIRTH":"19/07/2016"
},
{
"FIRST NAME":"Doe",
"LAST NAME":"Janette",
"DATE OF BIRTH":"19/07/2016"
}
]
@JSONField
Целевые объекты @JSONField:
- 1. Поле
- 2. Методы Setter и Getter
Примечание:Когда FastJson выполняет операции, он делает это на основе методов getter и setter, а не на основе полей.
Примечание:Если свойство является private, у него должен быть set-метод; в противном случае десериализация невозможна.
public @interface JSONField {
// Настройка порядка сериализации и десериализации; поддерживается только начиная с версии 1.1.42
int ordinal() default 0;
// Указывает имя поля
String name() default "";
// Указывает формат поля; полезно для форматов дат
String format() default "";
// Выполнять ли сериализацию
boolean serialize() default true;
// Выполнять ли десериализацию
boolean deserialize() default true;
}
2. Методы настройки JSONField
FieldInfo можно настроить на методах getter/setter или полях. Например:
2.1 Настройка на getter/setter
private int id;
@JSONField(name="ID")
public int getId() {return id;}
@JSONField(name="ID")
public void setId(int value) {this.id = id;}
}
2.2 Настройка на поле
@JSONField(name="ID")
private int id;
public int getId() {return id;}
public void setId(int value) {this.id = id;}
}
3. Использование format для настройки форматирования даты
// Настройка сериализации и десериализации даты для использования формата даты yyyyMMdd
@JSONField(format="yyyyMMdd")
public Date date;
}
4. Использование serialize/deserialize для указания полей, не подлежащих сериализации
@JSONField(serialize=false)
public Date date;
}
public class A {
@JSONField(deserialize=false)
public Date date;
}
5. Использование ordinal для указания порядка полей
По умолчанию fastjson сериализует Java-бин на основе алфавитного порядка fieldName. Вы можете указать порядок полей с помощью ordinal. Эта функция требует версии 1.1.42 или выше.
@JSONField(ordinal = 3)
private int f0;
@JSONField(ordinal = 2)
private int f1;
@JSONField(ordinal = 1)
private int f2;
}
FastJson также поддерживает сериализацию BeanToArray:
String jsonOutput= JSON.toJSONString(listOfPersons, SerializerFeature.BeanToArray);
Вывод:
[
[
15,
1469003271063,
"John Doe"
],
[
20,
1469003271063,
"Janette Doe"
]
]
Создание объектов JSON
Создание объектов JSON очень просто. Просто используйте JSONObject (объект JSON, предоставляемый fastJson) и JSONArray (объект массива JSON, предоставляемый fastJson).
Мы можем рассматривать JSONObject как Map<String,Object>, за исключением того, что JSONObject предоставляет более богатые и удобные методы для управления свойствами объекта. Давайте посмотрим на исходный код.

Аналогично, мы можем рассматривать JSONArray как List<Object> и можем считать JSONArray коллекцией объектов JSONObject.

Кроме того, поскольку JSONObject и JSONArray наследуются от JSON, оба также можно напрямую использовать для преобразования между строками формата JSON и JSON-объектами или JavaBeans. Однако во избежание путаницы мы по-прежнему используем JSON.
public void whenGenerateJson_thanGenerationCorrect() throws ParseException {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 2; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("AGE", 10);
jsonObject.put("FULL NAME", "Doe " + i);
jsonObject.put("DATE OF BIRTH", "2016/12/12 12:12:12");
jsonArray.add(jsonObject);
}
String jsonOutput = jsonArray.toJSONString();
}
Вывод:
[
{
"AGE":"10",
"DATE OF BIRTH":"2016/12/12 12:12:12",
"FULL NAME":"Doe 0"
},
{
"AGE":"10",
"DATE OF BIRTH":"2016/12/12 12:12:12",
"FULL NAME":"Doe 1"
}
]
Преобразование строк JSON в объекты Java
Теперь, когда мы научились создавать объекты JSON и преобразовывать объекты Java в строки JSON, нам нужно понять, как парсить JSON:
public void whenJson_thanConvertToObjectCorrect() {
Person person = new Person(20, "John", "Doe", new Date());
String jsonObject = JSON.toJSONString(person);
Person newPerson = JSON.parseObject(jsonObject, Person.class);
assertEquals(newPerson.getAge(), 0); // Если мы установим сериализацию в false
assertEquals(newPerson.getFullName(), listOfPersons.get(0).getFullName());
}
Мы можем использовать JSON.parseObject() для преобразования строк JSON в объекты Java.
Примечание: при десериализации в объект должен присутствовать конструктор по умолчанию без аргументов; в противном случае будет выброшено исключение:
com.alibaba.fastjson.JSONException: default constructor not found.
Ниже приведён простой пример теста:
Person [age=20, fullName=John Doe, dateOfBirth=Wed Jul 20 08:51:12 WEST 2016]
@JSONField deserializeНеобязательные параметры могут указывать поля, которые не следует десериализовать.
@JSONField(name = "DATE OF BIRTH", deserialize=false) private Date dateOfBirth;
Вывод:
Person [age=20, fullName=John Doe, dateOfBirth=null]
Использование ContextValueFilter для настройки преобразования JSON
В некоторых сценариях при фильтрации значений требуется получить информацию о владеющем JavaBean, включая его тип, поля, методы и т. д. В fastjson-1.2.9 предоставляется ContextValueFilter, аналогичный ValueFilter, предоставленному в предыдущих версиях, но с дополнительным доступным параметром BeanContext.
public void givenContextFilter_whenJavaObject_thanJsonCorrect() {
ContextValueFilter valueFilter = new ContextValueFilter () {
public Object process(
BeanContext context, Object object, String name, Object value) {
if (name.equals("DATE OF BIRTH")) {
return "NOT TO DISCLOSE";
}
if (value.equals("John")) {
return ((String) value).toUpperCase();
} else {
return null;
}
}
};
String jsonOutput = JSON.toJSONString(listOfPersons, valueFilter);
}
В приведённом выше примере мы скрыли поле DATE OF BIRTH и отфильтровали поля, имена которых не содержат John:
[
{
"FULL NAME":"JOHN DOE",
"DATE OF BIRTH":"NOT TO DISCLOSE"
}
]Использование NameFilter и SerializeConfig
NameFilter: Изменяет ключ во время сериализации.
SerializeConfig: Внутренне это map-контейнер, основная функция которого — настраивать и записывать класс сериализации, соответствующий каждому типу Java.
public void givenSerializeConfig_whenJavaObject_thanJsonCorrect() {
NameFilter formatName = new NameFilter() {
public String process(Object object, String name, Object value) {
return name.toLowerCase().replace(" ", "_");
}
};
SerializeConfig.getGlobalInstance().addFilter(Person.class, formatName);
String jsonOutput =
JSON.toJSONStringWithDateFormat(listOfPersons, "yyyy-MM-dd");
}
В примере мы объявили фильтр formatName с помощью анонимного класса NameFilter для обработки имён полей. Новый созданный фильтр связан с классом Person, затем добавлен в глобальный экземпляр, который является статическим свойством класса SerializeConfig.
Теперь мы можем легко преобразовывать объекты в формат JSON.
Обратите внимание, что мы используем toJSONStringWithDateFormat() вместо toJSONString(), что позволяет быстрее форматировать даты.
Результат вывода:
[
{
"full_name":"John Doe",
"date_of_birth":"2016-07-21"
},
{
"full_name":"Janette Doe",
"date_of_birth":"2016-07-21"
}
]