Как создать json файл java
Для создания JSON файла в Java необходимо выполнить следующие шаги:
1 Создать объект, который хотим сериализовать в JSON . Например, для этого можно создать класс с соответствующими полями:
public class Person private String name; private int age; public Person(String name, int age) this.name = name; this.age = age; > public String getName() return name; > public int getAge() return age; > >
2 Добавить зависимость в файл pom.xml (если используется Maven):
com.fasterxml.jackson.core jackson-databind 2.13.0
2.2 Для добавления зависимостей Jackson в Gradle проект необходимо в файл build.gradle добавить блок dependencies и указать необходимые зависимости:
dependencies implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.1' >
3 Создать объект ObjectMapper , который будет производить сериализацию в JSON :
ObjectMapper mapper = new ObjectMapper();
4 Создать объект класса, который хотим сериализовать:
Person person = new Person("Alice", 25);
5 Произвести сериализацию объекта в JSON :
mapper.writeValue(new File("person.json"), person);
В результате в корневой папке проекта будет создан файл person.json , содержащий JSON-представление объекта Person :
"name" : "Alice", "age" : 25 >
Java Как записать файл json по частям
В этой структуре есть 2 главных элемента, это documents:[0] и documents:[1]. При записи данных я создаю структуру, которая состоит из JSONObject и JSONArray. Код записи данных в файл:
//Способ 3 //Запись результата обработки в файл .json-------------- //outdir - Выходная директория (для .json) String outdir = Path[1]; //Path[1] - выходной путь из config.xml String newName = outdir + File.separator + datFile.replace("dat", "json"); File outPutFile_json = new File(newName); //Выходной файл .json для сохранения результата обработки try < //Создать root элемент JSONObject root = new JSONObject(); //Cоздать массив для документов JSONArray arrayOfDocs = new JSONArray(); //Положить arrayOfDocs в root root.put("documents", arrayOfDocs); //Заполнять этот массив результатами обработки каждого файла for (HashMap.Entry entry : myDocs.entrySet()) < //Текущий документ CustomDocument curDoc = (CustomDocument) entry.getValue(); SONObject obj = new JSONObject(); //Стата по текущему документу //Сохранить результат обработки текущего файла в arrayOfDocs curDoc.saveDataTojson(curDoc, obj); arrayOfDocs.add(obj); >//String message = root.toString(); if (!outPutFile_json.exists()) < outPutFile_json.createNewFile(); try (BufferedWriter writerPsp = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outPutFile_json), "UTF-8"))) < writerPsp.write(root.toJSONString()); //Записать измененный текст с найденными рубриками в json writerPsp.flush(); //Принудительно очищаем буфер BufferedWriter >catch (Exception e) < e.printStackTrace(); >> else < outPutFile_json.delete(); if (!outPutFile_json.exists()) < outPutFile_json.createNewFile(); try (BufferedWriter writerPsp = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outPutFile_json), "UTF-8"))) < writerPsp.write(root.toJSONString()); //Записать измененный текст с найденными рубриками в json writerPsp.flush(); //Принудительно очищаем буфер BufferedWriter >catch (Exception e) < e.printStackTrace(); >> >
Когда я хочу записать данные в структуру json я не могу заранее знать сколько будет этих главных объектов, поэтому могу записать файл только целиком, когда все что должно быть заполнено в root-documents будет заполнено, и тогда только сделать запись. Поэтому вопрос, как можно сделать запись в json по частям? Скажем например я получил все данные для элемента documents:[0] записал его в файл, потом получил данные documents:[1] записал его в файл, при этом, чтобы не нарушалась структура конечного файла.
Rukovodstvo
статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.
Чтение и запись JSON на Java
Что такое JSON? Нотация объектов JavaScript, или сокращенно JSON [https://www.json.org/], представляет собой формат обмена данными, который был представлен в 1999 году и получил широкое распространение в середине 2000-х годов. В настоящее время это фактически стандартный формат связи между веб-службами и их клиентами (браузерами, мобильными приложениями и т. Д.). Умение читать и писать — важный навык для любого разработчика программного обеспечения. Несмотря на то, что JSON был получен из JavaScript, это независимый от платформы формат. Ты
Время чтения: 9 мин.
Что такое JSON?
Нотация объектов JavaScript, или сокращенно JSON, — это формат обмена данными, который был представлен в 1999 году и получил широкое распространение в середине 2000-х годов. В настоящее время это фактически стандартный формат связи между веб-службами и их клиентами (браузерами, мобильными приложениями и т. Д.). Умение читать и писать — важный навык для любого разработчика программного обеспечения.
Несмотря на то, что JSON был получен из JavaScript, это независимый от платформы формат. Вы можете работать с ним на нескольких языках программирования, включая Java, Python, Ruby и многие другие. На самом деле любой язык, который может анализировать строку, может обрабатывать JSON.
Популярность JSON привела к его встроенной поддержке многими базами данных, последние версии PostgreSQL и MySQL содержат встроенную поддержку запросов к данным, хранящимся в полях JSON. Базы данных NoSQL, такие как MongoDB, были построены на этом формате и используют документы JSON для хранения записей, так же как таблицы и строки хранят записи в реляционной базе данных.
Одно из основных преимуществ JSON по сравнению с форматом данных XML — это размер документа. Поскольку JSON не имеет схемы, нет необходимости нести огромные структурные издержки, такие как пространства имен и оболочки.
JSON — это общий формат данных, который имеет шесть типов данных:
Давайте посмотрим на простой документ JSON:
Эта структура определяет объект, который представляет человека по имени «Бенджамин Уотсон». Здесь мы можем увидеть его данные, такие как его возраст, семейное положение и увлечения.
По сути, объект JSON — это не что иное, как строка. Строка, представляющая объект, поэтому объекты JSON часто называют строками JSON или документами JSON .
json-простой
Поскольку в Java нет встроенной поддержки JSON, прежде всего, мы должны добавить новую зависимость, которая предоставит нам ее. Для начала воспользуемся модулем json-simple , добавив его как зависимость Maven.
com.googlecode.json-simple json-simple
Этот модуль полностью соответствует спецификации JSON RFC4627 и обеспечивает основные функции, такие как кодирование и декодирование объектов JSON, и не имеет никаких зависимостей от внешних модулей.
Давайте создадим простой метод, который будет принимать имя файла в качестве параметра и записывать жестко закодированные данные JSON:
public static void writeJsonSimpleDemo(String filename) throws Exception
Здесь мы создаем экземпляр JSONObject , добавляя имя и возраст в качестве свойств. Затем мы создаем экземпляр класса JSONArray складывая два строковых элемента и помещая его в качестве третьего свойства нашего sampleObject . В конечном итоге мы преобразуем sampleObject в документ JSON, вызывая метод toJSONString() и записывая его в файл.
Чтобы запустить этот код, мы должны создать точку входа в наше приложение, которая могла бы выглядеть так:
public class Solution < public static void main(String[] args) throws Exception < writeJsonSimpleDemo("example.json"); >>
В результате выполнения этого кода мы получим файл с именем example.json в корне нашего пакета. Содержимое файла будет документом JSON со всеми введенными нами свойствами:
Большой! У нас только что был первый опыт работы с форматом JSON, мы успешно сериализовали в него объект Java и записали его в файл.
Теперь, с небольшой модификацией нашего исходного кода, мы можем прочитать объект JSON из файла и распечатать его на консоли либо полностью, либо распечатать выбранные отдельные свойства:
public static void main(String[] args) throws Exception < JSONObject jsonObject = (JSONObject) readJsonSimpleDemo("example.json"); System.out.println(jsonObject); System.out.println(jsonObject.get("age")); >public static Object readJsonSimpleDemo(String filename) throws Exception
Важно отметить, что метод parse() возвращает Object и мы должны явно привести его к JSONObject .
Если у вас есть искаженный или поврежденный документ JSON, вы получите исключение, подобное этому:
Exception in thread "main" Unexpected token END OF FILE at position 64.
Чтобы смоделировать это, попробуйте удалить последнюю закрывающую скобку > .
Копать глубже
Несмотря на то, что json-simple полезен, он не позволяет нам использовать пользовательские классы без написания дополнительного кода. Предположим, у нас есть класс, представляющий человека из нашего первоначального примера:
class Person < Person(String name, int age, boolean isMarried, Listhobbies, List kids) < this.name = name; this.age = age; this.isMarried = isMarried; this.hobbies = hobbies; this.kids = kids; >Person(String name, int age) < this(name, age, false, null, null); >private String name; private Integer age; private Boolean isMarried; private List hobbies; private List kids; // getters and setters @Override public String toString() < return "Person'; > >
Давайте возьмем документ JSON, который мы использовали в качестве примера в начале, и поместим его в файл example.json
Наша задача — десериализовать этот объект из файла в экземпляр класса Person Давайте сначала попробуем сделать это с помощью simple-json
Изменив наш main() , повторно используя статический readSimpleJsonDemo() и добавив необходимый импорт, мы получим:
public static void main(String[] args) throws Exception < JSONObject jsonObject = (JSONObject) readJsonSimpleDemo("example.json"); Person ben = new Person( (String) jsonObject.get("name"), Integer.valueOf(jsonObject.get("age").toString()), (Boolean) jsonObject.get("isMarried"), (List) jsonObject.get("hobbies"), (List) jsonObject.get("kids")); System.out.println(ben); >
Выглядит не очень хорошо, у нас много странных типов, но, похоже, он работает, не так ли?
Попробуем вывести на консоль массив kids Person а затем возраст первого ребенка.
System.out.println(ben.getKids()); System.out.println(ben.getKids().get(0).getAge());
Как мы видим, первый вывод консоли показывает, казалось бы, хороший результат:
но второй выдает Exception :
Exception in thread "main" java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to com.stackabuse.json.Person
Проблема здесь в том, что наше приведение типа к List не создавало два новых Person , а просто заполняло то, что там было — JSONObject в нашем текущем случае. Когда мы попытались копнуть глубже и узнать фактический возраст первого ребенка, мы столкнулись с ClassCastException .
Это большая проблема, которую, я уверен, вы сможете преодолеть, написав кучу очень умного кода, которым вы могли бы гордиться, но есть простой способ сделать это с самого начала.
Джексон
Библиотека, которая позволит нам делать все это очень эффективно, называется Jackson . Это очень распространено и используется в крупных корпоративных проектах, таких как Hibernate .
Давайте добавим это как новую зависимость Maven:
com.fasterxml.jackson.core jackson-databind
Базовый класс, который мы будем использовать, называется ObjectMapper , у него есть метод readValue() который принимает два аргумента: источник для чтения и класс, в который будет приведен результат.
ObjectMapper можно настроить с помощью ряда различных параметров, передаваемых в конструктор:
FAIL_ON_SELF_REFERENCESÂ Функция, которая определяет, что происходит, когда прямая ссылка на себя обнаруживается POJO (и для него не включена обработка идентификатора объекта): либо генерируется исключение JsonMappingException (если true), либо ссылка обрабатывается нормально (false). INDENT_OUTPUT Функция, которая позволяет включать (или отключать) отступы для базового генератора, используя симпатичный принтер по умолчанию, настроенный для ObjectMapper (и ObjectWriters, созданных из mapper). ORDER_MAP_ENTRIES_BY_KEYES Функция, которая определяет, сортируются ли записи карты сначала по ключу перед сериализацией или нет: если включен, при необходимости выполняется дополнительный этап сортировки (не требуется для SortedMaps), если отключен, дополнительная сортировка не требуется. USE_EQUALITY_FOR_OBJECT_ID Функция, которая определяет, сравнивается ли идентичность объекта, используя истинную идентичность объекта на уровне JVM (false); или метод equals (). Функция, которая определяет, как сериализуется тип char []: при включении будет сериализован как явный массив JSON (с односимвольными строками в качестве значений); при отключении по умолчанию они сериализуются как строки (что более компактно). WRITE_DATE_KEYS_AS_TIMESTAMPS Функция, которая определяет, будут ли даты (и подтипы), используемые в качестве ключей карты, сериализоваться как отметки времени или нет (в противном случае будут сериализованы как текстовые значения). WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS Функция, которая контролирует, должны ли числовые значения меток времени записываться с использованием наносекундных меток времени (включено) или нет (отключено); тогда и только тогда, когда тип данных поддерживает такое разрешение. WRITE_DATES_AS_TIMESTAMPS Функция, которая определяет, должны ли значения даты (и даты / времени) (и вещи на основе даты, такие как календари) быть сериализованы как числовые отметки времени (true; по умолчанию) или как что-то еще (обычно текстовое представление). WRITE_DATES_WITH_ZONE_ID Функция, которая определяет, следует ли сериализовать значения даты / даты и времени, чтобы они включали идентификатор часового пояса, в случаях, когда сам тип содержит информацию о часовом поясе.
Полный список перечисления SerializationFeature доступен здесь .
public static void main(String[] args) throws Exception
К сожалению, после запуска этого фрагмента кода мы получим исключение:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.stackabuse.json.Person]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
Судя по всему, мы должны добавить конструктор по умолчанию в класс Person
public Person() <>
Повторно запустив код, мы увидим еще одно исключение:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "isMarried" (class com.stackabuse.json.Person), not marked as ignorable (5 known properties: "hobbies", "name", "married", "kids", "age"])
Это немного сложнее решить, поскольку сообщение об ошибке не сообщает нам, что делать для достижения желаемого результата. Игнорирование свойства не является жизнеспособным вариантом, поскольку мы явно имеем его в документе JSON и хотим, чтобы оно было переведено в результирующий объект Java.
Проблема здесь связана с внутренней структурой библиотеки Джексона. Он извлекает имена свойств из геттеров, удаляя их первые части. В случае getAge() и getName() он работает отлично, но с isMarried() этого не происходит и предполагается, что поле должно называться married а не isMarried .
Жестокий, но рабочий вариант — мы можем решить эту проблему, просто переименовав геттер в isIsMarried . Давайте попробуем это сделать.
Больше никаких исключений не появляется, и мы видим желаемый результат!
Person, Person]> [Person, Person] 5
Хотя результат является удовлетворением, есть лучший способ обойти это , чем добавление другого is для каждого из ваших логических добытчиков.
Мы можем добиться того же результата, добавив аннотацию к isMarried() :
@JsonProperty(value="isMarried") public boolean isMarried()
Таким образом, мы явно сообщаем Джексону имя поля, и ему не нужно угадывать. Это может быть особенно полезно в тех случаях, когда имя поля полностью отличается от геттеров.
Заключение
JSON — это легкий текстовый формат, который позволяет нам представлять объекты и передавать их через Интернет или хранить в базе данных.
В Java нет встроенной поддержки манипуляций с JSON, однако есть несколько модулей, которые предоставляют эту функцию. В этом руководстве мы рассмотрели json-simple и Jackson , показывая сильные и слабые стороны каждого из них.
Работая с JSON, вы должны помнить о нюансах модулей, с которыми вы работаете, и тщательно отлаживать исключения, которые могут появляться.
Licensed under CC BY-NC-SA 4.0
Запишите данные JSON в файл на Java
В этом посте мы обсудим, как записать данные JSON в файл на Java.
1. Использование PrintWriter
Простое решение — создать новый PrintWriter экземпляр из потока вывода символов и использовать его write() метод для записи строки JSON в файл. Вы можете построить и передать FileWriter задано имя файла, используя указанную кодировку или кодировку по умолчанию для платформы. Обратите внимание, что если файл не существует, будет создан новый файл; в противном случае существующий файл будет усечен.
В следующем решении используется библиотека JSON-Java для создания companies.json файл в указанном месте с содержимым JSON .
