Saving uploaded image FileDescriptor using rest api /file

I am uploading photos from an iPad via the rest api /file using a POST method. The photos upload successfully and I can see them stored in FileStorage on the server and a row exists in SYS_FILE. I am also posting an entity that stores the photo information.

Now I want to display the uploaded photos on a screen using the Image component.

After plenty of research, it looks like using the Image.setSource(FileDescriptorResource.class).setFileDescriptor(myPhotoFileDescriptor) is the simplest technique.

I have added a column to my photo entity with the type of FileDescriptor [sys$FileDescriptor] and added the code below to the photo java file.

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "IMAGE_FILE_ID")
protected FileDescriptor imageFile;

public void setImageFile(FileDescriptor imageFile) {
    this.imageFile = imageFile;
}

public FileDescriptor getImageFile() {
    return imageFile;
}

My question is - when I post my photo entity via the rest api, how should I store the fileInfo returned by Cuba with the uploaded FileDescriptor information in my photo entity, then I can call photo.getImageFile() on image.setSource in my screen code.

When I trying passing just the fileInfo.id as the imageFile parameter in the post, I receive the error “Cannot deserialize an entity from JSON” for the rest api.

So how/what in the fileInfo needs to be stored in my imageFile FileDescriptor column? Or is there another technique you can recommend?

fileInfo {
    id (string, optional),
    name (string, optional),
    size (long, optional)
}

So that this works: -

image1.setSource(FileDescriptorResource.class).setFileDescriptor(photo.getImageFile());

Hi!

As I understood, you have already created FileDescriptor entity. As “imageFile” field is the object, we should use the following JSON:

{
  "someField1": "value1",
  "someField2": "value2",
  "imageFile": {
     "id": "4aa9a9d8-01df-c8df-34c8-c385b566ea05" // FileDescriptor id from fileInfo
  }
}

I created a simple example with HTML and jQuery. In this sample, we log in to the app, upload a file and create an entity that will contain this file.

  1. You should log in and get the access token which will be used in the subsequent requests. For example, we log in as administrator.
function login() {
      $.ajax({
          method: 'POST',
          url: 'http://localhost:8080/app/rest/v2/oauth/token',
          headers: {
             'Accept-Language': 'en',
             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
             'Authorization': 'Basic Y2xpZW50OnNlY3JldA=='
          },
          success: function (data) {
              oauthToken = data.access_token; // get the access token
          },
          data: {
              grant_type: 'password',
              username: 'admin',
              password: 'admin'
          }
      });
}
  1. Then we should upload a file. As response, we get json with fileInfo. Given “fileForm” consist of input with file type.
$("#fileForm").submit(function (e) {
      e.preventDefault();
      var file = $("#imageFile")[0].files[0]; // get file from input
      var url = 'http://localhost:8080/app/rest/v2/files?name=' + file.name; // send file name as parameter

      $.ajax({
          type: "POST",
          url: url,
          headers: {
              'Authorization': 'Bearer ' + oauthToken // add header with access token
          },
          processData: false,
          contentType: false,
          dataType: 'json',
          data: file,
          success: function (data) {
              fileInfo = data; // get the fileInfo
          }
      });
});

Then we can see in “External Files” screen our file.

  1. Now we can submit entity with two fields: name and imageFile - association field with FileDescriptor. As imageFile on the server side is FileDescriptor object, we should define “imageFile” as object like
    { “id”: id_from_file_info}.
$("#photoEntityForm").submit(function (e) {
      e.preventDefault();
      var photoEntity = {
          "name": $("#entityName").val(),
          "imageFile": { // association field with FileDescriptor
            "id": fileInfo.id
          }
      };
      var json = JSON.stringify(photoEntity);

      $.ajax({
          type: "POST",
          url: 'http://localhost:8080/app/rest/v2/entities/legit674$PhotoEntity',
          headers: {
              'Authorization': 'Bearer ' + oauthToken, // add header with access token
              'Content-Type': 'application/json'
          },
          dataType: 'json',
          data: json
      });
});

Now entity instance contains uploaded file.

The full html file:
index.html (2.9 KB)

Thank you Roman for your example. I will compare it to the process in my Swift code on the iPad, and see where I may be going wrong. I have it so that the FileDescriptor from my upload is now being saved in my photos entity, but I still cannot display the uploaded images with my Cuba screen.

I am on vacation now until the new year, so it might be a while before I get around to it.

Thanks, Mike.