Эта история не о Java Applet или Java WebStart, это история на чистом JavaScript, представленная г-жой. Гвитани и Др. Jackl, широко известный как GWT и J2CL.
В мире веб-браузеров JavaScript является королем, поэтому все веб-API основаны на JavaScript. Сеть разработчиков Mozilla (MDN) является источником истины для веб-API. Выглядит потрясающе и прекрасно все объясняет на примерах. Поэтому, если вы хотите создавать веб-приложения, вам обязательно понадобится документация MDN.
Урок 1: считайте Сеть разработчиков Mozilla (MDN) и Веб-API своими лучшими друзьями.
В этой истории я покажу вам, как мы можем использовать веб-API из транспилятора GWT / J2CL. Для этого я выбрал IndexedDB API. В документации по MDN приведено определение IndexedDB API:
IndexedDB - это низкоуровневый API для хранения на стороне клиента значительных объемов структурированных данных, включая файлы / большие двоичные объекты. Этот API использует индексы для обеспечения высокопроизводительного поиска этих данных. Хотя веб-хранилище полезно для хранения меньших объемов данных, оно менее полезно для хранения больших объемов структурированных данных. IndexedDB предлагает решение.
В IndexedDB следует реализовать следующую простую логику:
- Веб-приложение создаст базу данных IndexedDB, когда пользователь впервые откроет веб-приложение. Если база данных / хранилище данных недоступны, он создаст новую базу данных и вставит некоторые значения.
- Если мы откроем веб-приложение в следующий раз, а база данных уже существует, веб-приложение просто вставит некоторые значения. Это все.
Как мы узнали из статьи « Научитесь использовать везде: использование JavaScript API в Java для веб-браузера », нам нужны классы JsInterop, которые соединяют доступ с Java к IndexedDB API (вариант использования 2). Конечно, мы можем сами создавать классы JsInterop вручную, но в этом нет необходимости. Библиотека Elemental2 от Google здесь, чтобы помочь. Библиотека Elemental2 - это тонкий мост, который содержит коллекцию классов JsInterop для доступа к доступным веб-API. Мы можем использовать эти классы непосредственно в нашем веб-приложении Java. Итак, каковы шаги по использованию библиотеки Elemental2? Держи…
Первый шаг: вам нужно добавить необходимые зависимости Maven, в данном случае библиотеку IndexedDB Elemental2, в ваш pom.xml.
<dependency> <groupId>com.google.elemental2</groupId> <artifactId>elemental2-indexeddb</artifactId <version>1.1.0</version> </dependency>
Урок 2: прежде чем создавать классы JsInterop вручную, взгляните на библиотеку Elemental2, для большинства веб-API уже созданы классы JsInterop.
Второй шаг: Документация библиотеки Elemental2 для IndexedDB очень редка, поэтому вам необходимо использовать документацию MDN для IndexedDB. Документация отличная, и в ней есть несколько примеров. По теме IndexDB также есть несколько хороших документов и статей:
- Работа с IndexedDB от Google. В этой статье вам нужно понять разницу в работе с I ndexedDB API и обещанной мной библиотекой ndexedDB. В приложении у вас есть сравнение этих двух. В Elemental2 мы используем только API IndexedDB.
- Как использовать IndexedDB для создания прогрессивных веб-приложений: это очень хорошая статья для начала работы с IndexedDB.
- Некоторые общие примеры Elemental2
С приведенными выше документами и статьями вы готовы реализовать функции IndexedDB с помощью Elemental2.
Урок 3. Сначала найдите статьи и документацию по этой теме. Большинство статей посвящено JavaScript, но не паникуйте, вы поймете, что вам нужно делать на Java, поскольку он очень похож. Помните: модель программирования в JavaScript в основном основана на событиях, обещаниях, асинхронной модели программирования. API-интерфейсы Elemental2 будут очень похожи на API-интерфейсы JavaScript.
Третий шаг. Первая проблема, с которой я столкнулся, заключалась в том, чтобы проверить, доступна ли IndexedDB в веб-браузере с помощью следующего кода JavaScript:
if ('indexedDB' in window) {
console.log('This browser doesn\'t support IndexedDB');
return;
}
После запроса в GWT Gitter Chat (это определенно место, где можно попросить темы GWT / J2CL / Elemental2) я получил следующие решения на Java:
// General solution with JsInterop Window window = DomGlobal.window; if (Js.asPropertyMap(window).has("indexedDB") { logger.info("IndexedDB found"); } ... or ... // Use Elemental2 specific global variable IDBFactory indexedDB = IndexedDbGlobal.indexedDB; if (indexedDB != null) { logger.info("IndexedDB found"); }
После получения решения для первого препятствия остальное легко, поскольку все работает так же, как и в решении JavaScript. Очень интересна модель асинхронного программирования в JavaScript, которая необычна для разработчиков Java. Вот код для проверки базы данных / хранилища данных, когда его еще нет, поэтому вам нужно сначала создать его.
JavaScript:
openDBRequest.onupgradeneeded = function(event) { // Create object store from db or event.target.result };
Java с Lambda:
openDBRequest.onupgradeneeded = event -> { // Create object store from db or event.target.result return null; };
Как видите, код очень похож. Возвращение null в Java нехорошо, но необходимо, потому что библиотеки Elemental2 генерируются из Closure libraries (подробнее о генерации позже).
С помощью этих трех шагов вы сможете завершить реализацию простой логики для IndexedDB, описанной выше. Полный класс Java реализован в файле IndexedDbElemental2.java. Теперь мы можем запустить веб-приложение. Просто перейдите в каталог проекта Maven indexeddb-element2-example и выполните следующую команду:
mvn gwt:generate-module gwt:devmode
Мы можем отладить код Java, изменить его и перезагрузить. Все будет автоматически перенесено и перезагружено. Отладка работает очень хорошо, добавляя точку останова на исходных файлах в Google Chrome.
Чтобы увидеть результат, вам просто нужно перейти на панель Приложение в Chrome и найти слева область Хранилище. В меню IndexedDB вы найдете нашу сгенерированную базу данных и хранилище данных. Нажав кнопку Обновить в таблице, вы можете увидеть содержимое хранилища данных. В этом примере мы сохраняем объект Продукт при каждой перезагрузке index.html. При каждой перезагрузке мы создаем объект IndexedDbElemental2 и открываем базу данных. Вот класс EntryPoint AppEntryPoint:
package com.github.lofi.client; ... public class AppEntryPoint implements EntryPoint { @Override public void onModuleLoad() { new IndexedDbElemental2().openDb(); } }
Вот и все! Вы можете проверить весь файл IndexedDbElemental2, и вы увидите, что форма очень похожа на пример JavaScript, что позволяет нам очень легко реализовать, если мы можем найти несколько хороших статей по JavaScript или примеров по этой теме.
В заключение этой истории я хочу показать вам предысторию создания библиотек Elemental2. Библиотеки Elemental2 в основном генерируются с помощью JsInterop Generator. Вот описание проекта JsInterop Generator:
Генератор jsinterop - это программа Java, которая принимает закрывающие внешние файлы в качестве входных данных и генерирует классы Java, аннотированные аннотациями JsInterop. Этот проект используется для сборки Elemental2 [библиотека]. Любое другое использование является экспериментальным. Вы можете использовать его для создания API-интерфейсов Java для других библиотек JavaScript, но мы не предоставляем официальной поддержки. Тем не менее, не стесняйтесь открывать проблемы с помощью трекера проблем GitHub.
Важно знать, что мы действительно можем получить файлы JsInterop с помощью автоматической генерации, поскольку они являются всего лишь контрактами между миром Java и JavaScript.
Между тем существует еще один генератор Webtack Generator, который генерирует файлы JsInterop с большей ориентацией на Java и более приятными документами Javadoc. Вы помните return null выше? Здесь, на этой странице, вы можете увидеть различия файлов, сгенерированных JsInterop Generator (Elemental2) и Webtack Generator (также известный как Элементаль3). Для сравнения я создал тот же проект, но с использованием Webtack JsInterop для IndexedDB: indexeddb-element3-example. Проверьте это и взгляните на API IndexedDB (IndexedDbElemental3), он выглядит более чистым и более ориентированным на Java.
Урок 4: попробуйте сгенерировать нужные вам файлы JsInterop, проверьте, работает ли кто-нибудь на миссис Гвитани, а доктор Джекл уже сделал это, или используйте JsInterop Generator / Webtack Generator для их автоматической генерации. Помните: файлы JsInterop - это только договор между миром Java и JavaScript.
Миссис Гвитани и доктор Джекл не одни со своими транспиляторными инструментами. Транспилятор TypeScript и Транспилятор Kotlin в JavaScript очень похожи. Основное отличие заключается в том, что если вы используете Spring Boot (Java) на стороне сервера, у вас тот же язык, инструменты и пуленепробиваемый механизм также на стороне клиента в браузере, так что вы можете научиться один раз использовать везде!
На приведенной ниже схеме показан способ доступа к API веб-браузера из Java.
Послесловие: Привет от г-жи Гвитани и Др. Джекл и Надеюсь, вам понравятся четыре урока, упомянутые в этой истории. В следующий раз они покажут нам, как сделать этот пример IndexedDB более поддерживаемым и тестируемым с помощью внедрения зависимостей, Service / Шаблон репозитория и Mock-объект -, которые представляют собой пуленепробиваемый механизм при разработке приложений Java для разработчиков Java и от них.
Все примеры можно найти по адресу:
https://github.com/lofidewanto/jsinterop-simple-jsframework-example
Padlet для современного программирования GWT / J2CL:
https://bit.ly/GWTIntroPadlet