1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/xiandafu-beetl-json

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

beetl-json-logo.jpg

Описание:

  • Автор: Сян Дафу (также разработчик Beetl шаблонного языка)
  • Функциональность: Beetl-JsonTool является вспомогательным инструментом для шаблонного движка Beetl и предоставляет возможность сериализации объектов в формат JSON. Принцип работы основан на (Location:action)*, что делает его мощным и гибким инструментом. Он превосходит fastjson, jackson, gson по функциональности, основанной на аннотациях, а также превосходит jodd json, flexjson по способности сериализации, при этом занимая меньше 80К. Он позволяет сериализировать объекты в JSON с помощью стратегий сериализации без необходимости программирования или упаковки исходных объектов, при этом обеспечивая отличную производительность.

Примеры:

  • Пример API: JsonTool tool = new JsonTool(); String json = tool.serialize(user); String json1 = tool.serialize(user, "id:i")); //игнорировать свойство
    String json2 = JsonTool.serialize(list, "[1].id:i")); //игнорировать свойство id второго элемента //все свойства будут вызывать обратный вызов hibernateCheck String json2 = JsonTool.serialize(obj, "*:!hibernate"));

  • Примеры стратегий сериализации:

    • name:i игнорировать свойство name
    • id:i,obj.id:i игнорировать свойство id, игнорировать свойство id объекта obj. Можно объединять несколько стратегий сериализации, разделяя их запятыми
    • name:nn/myName/ свойство name выводить как myName
    • ~L/com.test.User/:o/name, age/ Сортировка свойств объекта User, name и age выводятся первыми, остальные свойства выводятся в соответствии с определением
    • [1].date:f/yyyy-MM-dd/ Форматирование свойства date второго элемента списка
  • Правила сериализацииПравила сериализации могут быть разными, каждый из которых содержит пару location и action, разделённые двоеточием, а сами правила сериализации разделены запятыми, что напоминает формат JSON, например:

name:i,user.id:i,~L/#ju.Collection*/:->null

Это означает три правила сериализации:

  • Первое игнорирует свойство name
  • Второе игнорирует свойство id объекта user
  • Третье более сложное, означает, что при сериализации объектов типа Collection и его подклассов, они будут присвоены null (#jl - псевдоним для java.util).

location и action могут содержать //, что напоминает скобки в языках программирования, внутри которых находятся параметры, например ~L/#ju.Collection*/## Действия Определяет действия, которые могут быть выполнены для соответствия, такие как игнорирование свойств, включение свойств, сортировка, переименование, условные проверки, присвоение значений, вызов обратных вызовов и т. д. * i: обозначает игнорирование, например, name:i — при встрече атрибута name его игнорировать. ~*:i/age,bir/ — игнорировать атрибуты типа age и bir класса, [1]:i — игнорировать вторую позицию, [name]:i — игнорировать элемент с ключом name, ~L/org. beetl. json. Foo/:i — игнорировать все атрибуты типа Foo. Атрибуты name и age всегда располагаются в начале. Остальные атрибуты располагаются в порядке (атрибуты сортируются с помощью встроенной AttributeComparator: примитивные типы впереди, затем POJO-типы, далее Java-типы, и в конце — коллекции).

  • u: обозначает использование атрибутов класса, например, ~*:u/name,age,bir/ — использовать атрибуты name, age и bir, остальные атрибуты игнорировать.
  • nn: обозначает изменение имени, {name:nn/myName/} — будет выведен myName.
  • ? : представляет собой условие, если условие выполнено, то используется определенный вывод, например, xxList:? null->[] — если коллекция xxList равна null, то выводится [].
  • $. xxx: используется для вызова метода текущего объекта, например, {ts:$. get} — не выводит ts, а выводит результат ts.get(). После вызова метода можно использовать -> для выполнения действия, например, "~L/java. util. Calendar*/:$.getTime->f/yyyy-MM-dd/" — при встрече с Calendar и его подклассами, сначала получается объект Date, затем форматируется.
  • f: используется для форматирования вывода, например, number:f/#.##/, также можно регистрировать собственные функции форматирования, например, если зарегистрирована функция форматирования Money, то number:fMoney будет вызывать Money для вывода.
  • ->: используется для прямого вывода, например, name:->'unknown'.
  • ! xxx: используется для вызова пользовательского действия, xxx — это зарегистрированное пользовательское действие.
  • f: используется для форматирования даты или числового типа, также можно вызывать пользовательские функции форматирования.
  • o: обозначает сортировку, например, ~L/xxxxClass/:o/name, age/.## Обработка циклических ссылокОбратите внимание, что при сериализации с циклическими ссылками beetl-json больше не сериализует уже сериализованные объекты, а вместо этого использует $ref:path для указания на предыдущий сериализованный объект, где path начинается с корневого узла, например:
"user": {"$ref":"$.list[0].user"}

Если также используются ci и cu, можно дополнительно вывести некоторые атрибуты, а не ограничиваться только "$ref":path. Например, если правило сериализации такое:

"~/User/:cu/name/"

это означает, что когда объект User встречается в циклической ссылке, помимо вывода $ref, также выводится атрибут name. Результат сериализации может выглядеть следующим образом:

"user": {"$ref":"$.list[0].user", "name": "xiandafu"}

Такой подход делает JSON более удобным для чтения, а некоторые фронтенд-фреймворки JavaScript могут использовать эти дополнительные атрибуты.

Расположение

Определяет место сериализации, будь то имя свойства, выражение свойства, элемент массива или класс.* Простое свойство, например, name:nn/myName/ — при встрече свойства name текущий экземпляр выведет myName, nn — это действие, указывающее на New Name.

  • Сложное свойство, например, user.age:->0 — при встрече свойства age в объекте user всегда выводится 0.
  • Регулярное выражение для свойства, например, /id|name/ — при встрече любого свойства id или name текущий экземпляр выведет их.
  • * — обозначает все свойства, например, *:! hibernate — все свойства будут проходить через hibernate перед сериализацией.
  • *. /reg/ — обозначает все свойства, соответствующие регулярному выражению, например, *. /id/ — все свойства с именем id.
  • ~L — за ним следует конкретный класс, например, ~L/com.test.User/:u/id,name/ — при сериализации все объекты типа User будут выводить только id и name.
    • Можно использовать , чтобы также соответствовать подклассам, например, ~L/com.test.User/.
    • Можно использовать JsonTool.addAlias("shortName", "longName"); для добавления псевдонимов для пакетов. Система по умолчанию добавляет ju для java.util и jl для java.lang. Если addAlias("com.test", "ct"), то ~L/com.test.User*/ можно сократить до ~L/#ct.User/.
  • [] — обозначает коллекцию.
    • [*] — позиция всех элементов коллекции.
    • [1] — позиция второго элемента коллекции.
    • [xxkey] — коллекция является Map, позиция элемента, соответствующего xxKey.
  • ~ — представляет тип текущего экземпляра:
    • ~d встречает тип даты, форматированное вывод. d — это сокращение для Java.Util.Date.
    • ~n представляет тип number. * ~c представляет тип коллекции.
    • ~d представляет тип даты.
    • ~*: представляет все типы текущего экземпляра, то есть все свойства и поля, например ~:o/age,name/ — свойства текущего экземпляра, выводятся в порядке age, name, остальное остается без изменений. location может быть выражением свойства obj.aaa.xx — указывает на свойство xx свойства aa объекта obj.
  • obj./.*str/ — указывает на все свойства объекта obj, заканчивающиеся на str, .*str — это регулярное выражение.
  • obj.~* — указывает на все свойства объекта obj.
  • obj[1].name — указывает на свойство name второго элемента коллекции obj.
  • obj[*].name — указывает на свойство name всех элементов коллекции obj.
  • ["key"].name — указывает на свойство name элемента с ключом key в map.
  • obj.aaa.* — указывает на все свойства свойства aa объекта obj, например obj.aaa.*:i/users,orgs/
  • [*].tt.~L/#ct.User/:i/users,orgs/ — указывает на все свойства типа User в свойстве tt всех элементов коллекции, сериализация выводит только users и orgs.

Обратите внимание, что в настоящее время не поддерживается использование выражений свойств после ~L/Class/.

Примеры API: // Глобальные настройки, применимые ко всем объектам

	JsonTool tool = new JsonTool();
	tool.addLocationAction("~d", "f/yyyy.MM.dd/");
	tool.addLocationAction("~L/java.util.Calendar*/", "$.getTime->f/yyyy-MM-dd/");
	// Политика форматирования JSON, несколько locationAction разделены запятыми
	tool.addPolicy("~f:n/#.##/,~c:?null->[]");
	// По умолчанию используется компактный вывод, установка true включает переносы строк и отступы
	tool.pretty = true;
	tool.addAlias("loc", "org.beetl.json.test.location");
	// Сериализация объекта User
	String json = tool.serialize(User);
	// или указание стратегии сериализации, age, name выводятся первыми, подходят для объектов с особыми требованиями или объектов, которые нельзя аннотировать (третьи стороны)
	String json2 = tool.serialize(User, "~*:o/age,name/");
	// та же стратегия, но свойство name выводится как code
	String json2 = tool.serialize(User, "~*:o/age,name/,name:nn/code/");
	// та же стратегия, но передача двух стратегий в API
	String json2 = tool.serialize(User, "~*:o/age,name/", "name:nn/code/");
	// Сериализация объекта dept, Department и SysUser имеют отношение один ко многим, если два класса повторно используются, то пропускаются свойства dept и users, вызывающие повторное использование
	String json1 = tool.serialize(dept, "~L/#loc.SysUser/:ci/dept/,~L/#loc.Department/:ci/users/");## Примечания

По умолчанию можно использовать аннотации для определения стратегии сериализации.```java @Json( policys={ @JsonPolicy(location="name", action="nn/newUserName/"), @JsonPolicy(location="deleteList", action="?empty->[]") } ) public class User{ String name="joel"; int age =12; double salary=12.32266; Customer customer = new Customer(); List list = new ArrayList(); List deleteList = null; //getter and setter методы должны быть реализованы, но здесь они опущены }


```java
@Json(
	policys={
			@JsonPolicy(location="name", action="nn/userName/")			
	}
)
class Customer{
	String name="lijz";
	int age=11;
	Date bir = new Date();
	//getter and setter методы должны быть реализованы, но здесь они опущены
}

Расширение действий

Разрешено создавать пользовательские действия для обработки специальных требований сериализации. Действия могут реализовывать интерфейс IValueAction для обработки объектов, а также интерфейсы IKeyAction, IInstanceAction и другие.

В следующем примере кода реализован интерфейс IValueAction, который проверяет, был ли объект действительно загружен Hibernate, и если нет, то не сериализует его, что позволяет избежать проблем с ленивой загрузкой Hibernate.```java JsonTool tool = new JsonTool(); tool.addAction("hibernate", new IValueAction() {

@Override
public int getIndex() {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public ActionReturn doit(OutputNodeKey field, Object value,
		OutputNode thisNode, JsonWriter w) {
	if (value instanceof HibernateProxy) { // объект-прокси Hibernate
        LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer();
        if (initializer.isUninitialized()) {
            return new ActionReturn(null, ActionReturn.RETURN);
        }
    } else if (value instanceof PersistentCollection) { // коллекция связанных сущностей
        PersistentCollection collection = (PersistentCollection) value;
        if (!collection.wasInitialized()) {
            return new ActionReturn(null, ActionReturn.RETURN);
        } else if (collection.getValue() == null) {
            return new ActionReturn(null, ActionReturn.RETURN);
        }
    }
    return new ActionReturn(value, ActionReturn.CONTINUE);
}

});

String joins = "location,customer"; List cars = service.findAll(joins); String json = tool.serialize(cars, "*:!hibernate");


Можно создать пользовательскую функцию форматирования, как показано ниже.

```markdown
JsonTool.addFormat("simple", new MyDateFormatter());

public class MyDateFormatter implements Format {

    public Object format(Object o) {
        // TODO Auto-generated method stub
        return "2015";
    }

}

// Сериализация item, её свойство bir форматируется по правилу simple, f — это префикс действий, simple — зарегистрированный формат
String json1 = JsonTool.serialize(item, "bir:fsimple");

Основные API:* JsonTool. addLocationAction(String loc, String action) : добавляет глобальную стратегию сериализации, например, JsonTool. addLocationAction("~d", "f/yyyy.MM.dd/");

  • JsonTool. pretty : по умолчанию используется компактный вывод, если установить true, то будет использоваться отступ и перенос строки
  • JsonTool. serialize(Object o) : сериализует объект, возвращает String
  • JsonTool. serialize(Object o, Writer w) : сериализует объект в Writer
  • JsonTool. serialize(Object o, String policy) : сериализует объект, возвращает String, и использует дополнительную стратегию сериализации
  • JsonTool. serialize(Object o, String... policy) : сериализует объект, использует несколько стратегий сериализации
  • JsonTool. serialize(Object o, Writer w, String policy) : сериализует объект в Writer, и использует дополнительную стратегию сериализации
  • JsonTool. serialize(Object o, Writer w, String... policy) : сериализует объект в Writer, использует несколько стратегий сериализации
  • JsonTool. addFormat(Class type, Format format) : регистрирует функцию форматирования, затем можно использовать f для форматирования этого свойства, например, xxx:f, f также может использовать параметры, например, xxx:f/yyy/, параметры передаются в класс Format
  • JsonTool. addAction("hibernate", new HibernateAction()) : регистрирует действие
  • JsonTool. addAlias(String shortName, String name) : добавляет псевдоним
  • JsonTool.attributeErrorHander: обрабатывает ошибки получения атрибутов, по умолчанию выбрасывает исключение, также можно реализовать AttributeErrorHandler для создания собственной обработки ошибок, например, Hibernate lazy load выбрасывает исключение, можно установить этот интерфейс для игнорирования ошибок

Код примера @RequestMapping(value = "/json.html", method = RequestMethod.GET) @ResponseBody public List index1(HttpServletRequest req) { List list = new ArrayList(); list.add(1); list.add(2); list.add(new Date()); return list; }

Если вы хотите использовать кастомную стратегию сериализации, а не аннотации, вы можете использовать объект SerObject

@RequestMapping(value = "/json2.html", method = RequestMethod.GET)
@ResponseBody
public SerObject index2(HttpServletRequest req) {
	List list = new ArrayList();
	list.add(1);
	list.add(2);
	list.add(new Date());
	SerObject s = new SerObject(list, "[1]:i"); // игнорировать второй элемент
	return s;
}

Для более подробных примеров обратитесь к коду юнит-тестов https://git.oschina.net/xiandafu/beetl-json/tree/master/test

Maven зависимость

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>btjson</artifactId>
    <version>0.94</version>
</dependency>

Следующие шаги:

  • Оптимизация производительности, чтобы занять первое или второе место, будет добавлена оптимизация с использованием asm и unsafe
  • Простая десериализация, общая размерность не должна превышать 140к.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/xiandafu-beetl-json.git
git@api.gitlife.ru:oschina-mirror/xiandafu-beetl-json.git
oschina-mirror
xiandafu-beetl-json
xiandafu-beetl-json
master