3.10.8. Хранилище файлов

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

Механизм работы с файлами состоит из следующих частей:

  • Сущность FileDescriptor - описатель загруженного файла (не путать с java.io.FileDescriptor), позволяющий ссылаться на файл из объектов модели данных.

  • Интерфейс FileStorageAPI - доступ к хранилищу файлов на уровне Middleware. Основные методы:

    • saveStream() - сохранить содержимое файла, переданное в InputStream, по данным указанного FileDescriptor.

    • openStream() - вернуть содержимое файла, указанного объектом FileDescriptor, в виде открытого InputStream.

  • Класс FileUploadController - контроллер Spring MVC, позволяющий отправлять файлы с клиентского уровня на Middleware посредством HTTP POST запросов.

  • Класс FileDownloadController - контроллер Spring MVC, позволяющий получать файлы с Middleware на клиентский уровень посредством HTTP GET запросов.

  • Визуальные компоненты FileUpload и FileMultiUpload - позволяют загрузить файлы с компьютера пользователя на клиентский уровень приложения, и затем организовать их передачу на Middleware.

  • Интерфейс FileUploadingAPI - промежуточное хранилище загружаемых файлов на клиентском уровне. Используется вышеупомянутыми компонентами для загрузки файлов на клиентский уровень. В прикладном коде используется метод putFileIntoStorage(), перемещающий файл в постоянное хранилище на Middleware.

  • FileLoader - интерфейс для работы с хранилищем файлов, предоставляющий единый набор методов как на уровне Middleware, так и на клиентском уровне.

  • ExportDisplay - интерфейс клиентского уровня, позволяющий выгружать различные ресурсы приложения на компьютер пользователя. Для получения файлов из хранилища можно использовать метод show(), принимающий FileDescriptor. Экземпляр ExportDisplay можно получить либо вызовом статического метода AppConfig.createExportDisplay(), либо инжекцией в класс контроллера.

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