Как отдать клиенту записанный на диск файл

Добрый день.
Обстановка: создан и записан на диск сервера XML файл (напр c:\test.xml)
Задача: отдать этот файл на компьютер клиента
Вопрос: как отдать файл с помощью ExportDisplay?

Решение с сохранением файла в хранилище :

       fileDescriptor = metadata.create(FileDescriptor.class);
        fileDescriptor.setName(filePath);
        fileDescriptor.setExtension("xml");
        fileDescriptor.setCreateDate(new Date());

        try {
            fileLoader.saveStream(fileDescriptor, () -> {
                try {
                    return new FileInputStream(filePath);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            });
        } catch (FileStorageException e) {
            e.printStackTrace();
        }
        dataManager.commit(fileDescriptor);

        exportDisplay.show(fileDescriptor, ExportFormat.XML);

Можно ли отдать файл без сохранения в хранилище? Файл временный, на сервере не нужен.

Должно получиться, если на среднем слое (в сервисе) прочитать файл в байтовый массив, а на клиента в UI отдавать из байтового массива: exportDisplay.show(new ByteArrayDataProvider(myService.getFileByteArray()), "test.txt", ExportFormat.TEXT);
Ну, естественно, физически файл должен храниться на том же сервере, где размещен средний слой.

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

...tomcat/work/app-core/filestorage

На самом деле все валится в

...\Tomcat 9.0\bin

Не подскажите, чего подкрутить, чтобы было правильно?

fileLoader.saveStream без вариантов сохраняет файлы внутри корня хранилища, которое определяется свойством приложения cuba.fileStorageDir.
Если свойство на задано - тогда внутри рабочего каталога приложения (свойство cuba.dbDir).

Ну или если “на самом деле все валится в …\Tomcat 9.0\bin” - это про пример кода, который у вас приведен выше, а вы его и развертываете и тестируете на одном ПК, то скорее всего, файл в \Tomcat 9.0\bin попадет после exportDisplay.show(fileDescriptor, ExportFormat.XML).

Вроде у вас была задача взять файл на сервере по некому физическому пути и отдать его на клиента.
Тогда приведенный вами выше код, должен работать на сервере. И тут же у вас, в последней строке идет exportDisplay.show(fileDescriptor, ExportFormat.XML), что по сути должно вызываться в коде UI (если файл надо отдать клиенту).
Ну или я окончательно запутался.

То ли я такой, то ли лыжи не едут. Чего то простого еще не знаю:

  1. В контроллере:
public void xmlExport() {
    try {
       dbf = DocumentBuilderFactory.newInstance();
       db  = dbf.newDocumentBuilder();
       doc = db.newDocument();
       Формирую DOM ....
    }  catch (ParserConfigurationException | DOMException e) {
            e.printStackTrace();
}         } finally {
            if (doc != null) {
                String filePath = "pn-1.xml";
                exportDisplay.show(putFileToStorageService.writeDocument(doc, filePath), ExportFormat.XML);
            }
        }
  1. Сервис :
    @Override
    public FileDescriptor writeDocument(Document doc, String file_data) throws TransformerFactoryConfigurationError {
        try {
            doc.setXmlStandalone(true);
            Transformer trf = TransformerFactory.newInstance().newTransformer();
            DOMSource src = new DOMSource(doc);
            trf.setOutputProperty(OutputKeys.ENCODING, "windows-1251");
            FileOutputStream fos = new FileOutputStream(file_data);
            StreamResult result = new StreamResult(fos);
            trf.transform(src, result);
        } catch (TransformerException | IOException e) {
            e.printStackTrace();
        }

        FileDescriptor fileDescriptor = metadata.create(FileDescriptor.class);
        fileDescriptor.setName(file_data);
        fileDescriptor.setExtension("xml");
        fileDescriptor.setCreateDate(new Date());

        try {
            fileLoader.saveStream(fileDescriptor, () -> {
                try {
                    return new FileInputStream(file_data);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            });
        } catch (FileStorageException e) {
            e.printStackTrace();
        }
        dataManager.commit(fileDescriptor);
        return fileDescriptor;
    }

В результате файл попадает в bin.
Помогите сняться с ручника, а?

Обратите внимание, в документации есть пример использования ByteArrayDataProvider:
https://doc.cuba-platform.com/manual-7.2-ru/file_download.html

Вам не нужно сохранять файл на диск, если только он не настолько большой, что не умещается в оперативную память.
Используйте ByteArrayOutputStream вместо FileOutputStream, сохраняйте документ в byte[], и потом выдавайте это в ExportDisplay.