Как записать загружаемое изображение из FileUploadField не в файловое хранилище, а в соседнее Blob поле?

Хочу хранить картинки и рисунки не в файловом хранилище в виде файлов. А в базе данных в специально предназначенном для этого поле ByteArea. Естественно что код примера обработки файла в контроллере, я уже весь изучил, но он заточен на запись файла в файловое хранилище. А мне нужно чтобы он писал в поле image ByteArea PostgreSQL.

Вот код из примера, судя по всему мне его надо как-то немного модифицировать, чтобы записать файл в поле Image.

@Inject
private FileUploadField image_idField;
@Inject
private FileUploadingAPI fileUploadingAPI;
@Inject
private DataManager dataManager;
@Inject
private Notifications notifications;

@Subscribe("image_idField")
public void onUploadFieldFileUploadSucceed(FileUploadField.FileUploadSucceedEvent event) {
    File file = fileUploadingAPI.getFile(image_idField.getFileId());
    if (file != null) {
        notifications.create()
                .withCaption("File is uploaded to temporary storage at " + file.getAbsolutePath())
                .show();
    }

    FileDescriptor fd = image_idField.getFileDescriptor();
    try {
        fileUploadingAPI.putFileIntoStorage(image_idField.getFileId(), fd);
    } catch (FileStorageException e) {
        throw new RuntimeException("Error saving file to FileStorage", e);
    }
    dataManager.commit(fd);
    notifications.create()
            .withCaption("Uploaded file: " + image_idField.getFileName())
            .show();
}

@Subscribe("image_idField")
public void onUploadFieldFileUploadError(UploadField.FileUploadErrorEvent event) {
    notifications.create()
            .withCaption("File upload error")
            .show();
}     

}

Добрый день!

Надеюсь, вот этот пример кода вам поможет:

@UiController("forumimage_NewEntity.edit")
@UiDescriptor("new-entity-edit.xml")
@EditedEntityContainer("newEntityDc")
@LoadDataBeforeShow
public class NewEntityEdit extends StandardEditor<NewEntity> {
    @Inject
    private FileUploadingAPI fileUploadingAPI;
    @Inject
    private Notifications notifications;
    @Inject
    private FileUploadField uploadField;

    @Subscribe("uploadField")
    public void onUploadFieldFileUploadSucceed(FileUploadField.FileUploadSucceedEvent event) {
        File file = fileUploadingAPI.getFile(uploadField.getFileId());
        if (file != null) {
            notifications.create()
                    .withCaption("File is uploaded to temporary storage at " + file.getAbsolutePath())
                    .show();
        }
        byte[] bytes = uploadField.getBytes();
        getEditedEntity().setImage(bytes);
    }
}

С уважением,
Мария

2 симпатии

Добрый день !

Спасибо я попробую, я пока что с адаптивным дизайном разбираюсь. Как закончу, вернусь к Upload Image файлов в поле ByteArea о результатах напишу.

Добрый день !

Все нормально, всё работает, данные фотографии в поле Image сохраняются и обратно в форме нормально высвечиваются. Но CUBA 7.2.4 выдает предупреждение, что метод uploadField.getBytes() устарел и рисует его в перечеркнутом виде.

byte[] bytes = uploadField.getBytes();
getEditedEntity().setImage(bytes);

А чем конструкцию uploadField.getBytes() заменить не понятно.

Это не обязательно в данном случае, но если размер файла потенциально большой, то лучше получить файл который загрузился на диск и работать уже с ним:

File file = fileUploadingAPI.getFile(uploadField.getFileId());
2 симпатии

Добрый день !

Вот так вот сделал

@Inject
private FileUploadingAPI fileUploadingAPI;
@Inject
private Notifications notifications;
@Inject
private FileUploadField uploadField;
@Subscribe("uploadField")

public void onUploadFieldFileUploadSucceed(FileUploadField.FileUploadSucceedEvent event) throws IOException, FileStorageException {
getEditedEntity().setFile_name(uploadField.getFileName());
File file = fileUploadingAPI.getFile(uploadField.getFileId());
byte[] bytes = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(bytes);
getEditedEntity().setImage(bytes);
fis.close();
fileUploadingAPI.deleteFile(uploadField.getFileId());
}

Всё вроде работает, не знаю только нужно ли мне самому удалять файл после загрузки его в базу данных из хранилища или он сам удаляется, если я не ставлю в uploadField опцию IMMEDIATE.

Ну в общем то сам нашел ответ, что файл из файлового хранилища нужно самому принудительно удалять командой fileUploadingAPI.deleteFile(uploadField.getFileId());
а иначе на сервере будет много лишних файлов, которые к тому же уже загружены в базу данных. .

Ну всё, проблема решена, всем спасибо.

1 симпатия