JNLP API Java

JNLP API JavaJNLP API позволяет неподписанному приложению запускаться в «песочнице» и в то же время получать безопасный доступ к локальным ресурсам. Например, в нем предусмотрены службы для загрузки и сохранения файлов. Приложения не видит файловой системы и не может специфицировать имена файлов.

Вместо этого отображается файловый диалог, и пользователь программы выбирает файл. Перед появлением диалогового окна для выбора файлов пользователь получает предупреждение и должен выразить согласие на продолжение работы. Более того, на самом деле API не предоставляет программе доступа к объекту File.

В частности, приложение не может самостоятельно обнаружить файл. Поэтому программистам предоставляются инструменты для реализации действий открытия и сохранения файла, но системная информация максимально скрыта от сомнительных приложений.API предоставляет разработчику описанные ниже возможности:

  • Загрузка и сохранения файлов.
  • Доступ к буферу обмена.
  • Печать.
  • Отображение документа в стандартном браузере.
  • Хранение и извлечение конфигурационных данных.
  • Средства, позволяющие убедиться в том, что выполняется только один экземпляр приложения(данная возможность была реализована в Java SE 5.0).

Чтобы воспользоваться этими возможностями, необходимо применить класс ServiceManager, примерно так:

Если соответствующая функция оказалась недоступной, генерируется исключение UnavailableServiceException.

Для компиляции программы, использующей интерфейс JNLP API, необходимо указать в составе пути для поиска классов файл javaws.jar. Этот файл находится в подкаталоге jre/lib каталога JDK.

Теперь перейдем к обсуждению наиболее полезных возможностей JNLP. Чтобы сохранить файл, следует указать в диалоговом окне предложения о первоначальном пути и расширения файлов, а также сохраняемые данные и предполагаемое имя файла. Рассмотрим пример:

Данные должны быть доставлены в поток InputStream. Иногда эта задача оказывается довольно сложной. Программа, приведенная в конце статьи, использует описанную ниже стратегию.

  1. Создается экземпляр класса ByteArrayOutputStream, предназначенный для хранения байтов, подлежащих записи на диск.
  2. Создается экземпляр класса PrintStream, посылающий эти данные в поток ByteArrayOutputStream.
  3. Информация, подлежащая сохранению в потоке печати, выводится в PrintStream.
  4. Создается экземпляр класса ByteArrayInputStream, считывающий сохраненные байты.
  5. Поток передается методу saveFileDialog().

Более подробно потоки описываются в данной рубрике. Пока же мы можем не обращать внимания на детали, указанные в демонстрационной программе в конце урока.

Чтобы считать данные из файла, используется класс FileOpenService. Его метод openFileDialog() получает первоначальный путь и расширения файлов и возвращает объект класса FileContents. Затем можно вызвать метод getInputStream() и считать данные из файла. Если пользователь не выбрал файл, метод openFileDialog() возвращает значение null.

Обратите внимание, что ваше приложение не знаете имени и места расположения файла. В противоположность этому, если вы хотите открыть определенный файл, то используете ExtendedService.

Пользователь вашей программы должен разрешить доступ к файлу(смотрите рис.2).

JNLP API JavaРис.2. Предупреждение о доступе к файлу

Для того чтобы отобразить документ в стандартном браузере(аналогично методу showDocument() для аплетов), применяется интерфейс BasicService. Учтите, что в некоторых системах стандартный браузер не установлен.

Существует устаревший метод PersistentService(), позволяющий приложению сохранять небольшие объемы информации о настройках и извлекать ее, если приложение запускается вновь. Эта возможность напоминает механизм cookie, применяемый при работе с протоколом HTTP. В качестве ключей используются URL. Эти URL не обязательно должны ссылаться на реальные ресурсы. Они лишь представляют собой удобную иерархическую схему именования файлов.

По каждому URL-ключу приложение может записать произвольные двоичные данные. Объем записи может быть ограничен и размером блока.

Для того чтобы изолировать приложение друг от друга, каждое приложение должно использовать URL, начинающейся с имени сервера, содержащего его код который указан в JNLP-файле. Например, если приложение загружено с Web-страницы https://pro-java.ru/apps, то оно может использовать лишь ключи, имеющие вид https://pro-java.ru/apps/subkey1/subkey2/… Попытка получить доступ к другим ключам будет заведомо неудачной.

Чтобы определить адрес сервера, на котором хранится код, приложение может вызвать метод getCodebase() класса BasicService.

Новый ключ создается с помощью метода create() класса PersistenceService:

Для доступа к информации, связанной с конкретным ключом, вызывается метод get(). Этот метод возвращает экземпляр класса FileContents, с помощью которого можно читать и записывать данные, соответствующие указанному ключу.

FileConents contents = service.get(url);
InputStream in = contents.getInputStream();
OutputStream out = contents.getOutputStream(true);
// true = перезапись

К сожалению, определить, существует указанный ключ или его нужно создать заново, довольно сложно. Мы может лишь надеяться, что ключ существует, и вызывать метод get. Если при этом генерируется исключение FileNotFoundException, необходимо создать новый ключ.

Начиная с Java SE 5.0, и приложение Java Web Start, и аплеты могут выводить данные на печать, используя обычные средства API. При этом отображается диалоговое окно, запрашивающее у пользователя согласие на доступ к принтеру.

Программа, код которой приведен ниже, представляет собой модификатор приложения, реализующего калькулятор. Этот калькулятор имеет виртуальную бумажную ленту, на которую записываются результаты всех вычислений. Список всех предыдущих вычислений можно сохранять и считывать из файла.

Для демонстрации постоянного хранения данных приложение позволяет задавать заголовок фрейма. Если программу запустить вновь, она извлечет этот заголовок из постоянного хранилища(смотрите рис.3).

jnlp-api-java-2Рис.3. Приложение WebStartCalculator

Вот исходный код программы: