Upload an image
This document covers sample implementation for upload template POST handler uploading images on page submission or on demand using supporting dynamic action Upload Images on Demand. All examples uploads images to the plug-in sample application table UC_FROALA_SAMPLE_BLOBS. The difference between handlers is complexity of PL/SQL code, whether handler uses default query parameters, custom parameters or uses image checksum to secure display handler.
:::note handler features
- can be combined with handler displaying an image Simple
- can be combined with handler browsing images Simple
- doesn’t use default parameters and the URL to displaying image handler (page item attribute Image GET URL) is hardcoded in the code
:::
:::note handler features
- can be combined with handler displaying an image Simple
- can be combined with handler browsing images Default Parametrs
- uses default parameters to fetch page item attribute Image GET URL from the plug-in access token
:::
:::note handler features
- can be combined with handler displaying an image Simple
- can be combined with handler browsing images Custom parameters
- uses default parameters to fetch page item attribute Image GET URL from the plug-in access token
- uses custom parameter
folderto save additional information about image in the database - requires definining custom parameter using Initialization JavaScript Code and option imageUploadParams or using the supporting dynamic action plug-in Upload Parameters
:::
:::note handler features
- must be combined with handler displaying an image Image checksum
- must be combined with handler browsing images Image checksum
- uses default parameters to fetch page item attribute Image GET URL from the plug-in access token
- uses access token static function encode to create image checksum securing display handler using query parameter
- doesn’t expose uploaded image id in the database
:::
Requirements
Section titled “Requirements”The upload handler must meet the following requirements:
- must use POST method
- must be compilable at the run time
- must return 200 HTTP status code
- must print JSON describing uploaded image
Handler definition
Section titled “Handler definition”| Attribute | Value |
|---|---|
| RESTful Service Module | A custom RESTservice |
| Module Base Path | /customrest/ |
| URI Template | upload-simple |
| Full URL | https://example-domain.com/ords/workspacename/customrest/upload-simple |
| Handler Method | POST |
| Source Type | PL/SQL |
| Mime Types Allowed | Not defined |
| Attribute | Value |
|---|---|
| RESTful Service Module | A custom RESTservice |
| Module Base Path | /customrest/ |
| URI Template | upload-default |
| Full URL | https://example-domain.com/ords/workspacename/customrest/upload-default |
| Handler Method | POST |
| Source Type | PL/SQL |
| Mime Types Allowed | Not defined |
| Attribute | Value |
|---|---|
| RESTful Service Module | A custom RESTservice |
| Module Base Path | /customrest/ |
| URI Template | upload-custom |
| Full URL | https://example-domain.com/ords/workspacename/customrest/upload-custom |
| Handler Method | POST |
| Source Type | PL/SQL |
| Mime Types Allowed | Not defined |
| Attribute | Value |
|---|---|
| RESTful Service Module | A custom RESTservice |
| Module Base Path | /customrest/ |
| URI Template | upload-checksum |
| Full URL | https://example-domain.com/ords/workspacename/customrest/upload-checksum |
| Handler Method | POST |
| Source Type | PL/SQL |
| Mime Types Allowed | Not defined |
Handler parameters
Section titled “Handler parameters”The upload handler doesn’t require registering any resource parameters as long as REST specific bind variable :status_code is used to set request HTTP status.
Handler Source
Section titled “Handler Source”declare v_image_blob blob := :body; v_image_mime_type varchar2(4000) := :content_type; v_image_link varchar2(4000); v_file_id number;
/* without default parameters image filename is not available */ v_file_name varchar2(4000) := 'filename';begin
insert into UC_FROALA_SAMPLE_BLOBS( FILE_NAME, FILE_CONTENT, FILE_MIMETYPE, SESSION_ID ) values( v_file_name, v_image_blob, v_image_mime_type, null ) returning ID into v_file_id;
/* The URL to RESTful service GET handler is hardcoded */ v_image_link := 'https://example-domain.com/ords/workspacename/customrest/display-simple/'||v_file_id;
/* print JSON to the browser buffer */ apex_json.open_object; apex_json.write('link' , v_image_link, true); apex_json.write('data-image-id', v_file_id , true); apex_json.close_object;
/* set HTTP status code */ :status_code := 200;exception when others then :status_code := 500; apex_json.open_object; apex_json.write('error', SQLERRM); apex_json.close_object;end;declare v_image_blob blob := :body; v_image_mime_type varchar2(4000) := :content_type; v_image_link varchar2(4000); v_file_id number; v_access_token uc_rte_access_token;
/* default query parameters computed on page load */ //highlight-next-line v_param_accessToken varchar2(32767) := :accessToken; //highlight-next-line v_param_sessionId varchar2(32767) := :sessionId; //highlight-next-line v_param_filename varchar2(32767) := :filename;begin /* validate access token to check if it's authorised upload request */ //highlight-next-line v_access_token := uc_rte_access_token.create_from_token( v_param_accessToken );
if v_access_token.is_valid = 0 then raise_application_error(-20001, 'Invalid access token'); end if;
insert into UC_FROALA_SAMPLE_BLOBS( FILE_NAME, FILE_CONTENT, FILE_MIMETYPE, SESSION_ID ) values( //highlight-next-line v_param_filename, v_image_blob, v_image_mime_type, //highlight-next-line v_param_sessionId ) returning ID into v_file_id;
/* Use display URL defined for the plug-in instance */ v_image_link := v_access_token.url_get_image||v_file_id;
/* print JSON to the browser buffer */ apex_json.open_object; apex_json.write('link' , v_image_link, true); apex_json.write('data-image-id', v_file_id , true); apex_json.close_object;
/* set HTTP status code */ :status_code := 200;exception when others then if SQLCODE = -20001 then :status_code := 403;
else :status_code := 500; apex_json.open_object; apex_json.write('error', apex_string.format('While uploading an image, an unexpected error was raised: %s', SQLERRM)); apex_json.close_object;
end if;end;declare v_image_blob blob := :body; v_image_mime_type varchar2(4000) := :content_type; v_image_link varchar2(4000); v_file_id number; v_access_token uc_rte_access_token;
/* default query parameters computed on page load */ v_param_accessToken varchar2(32767) := :accessToken; v_param_sessionId varchar2(32767) := :sessionId; v_param_filename varchar2(32767) := :filename;
/* custom query parameter "folder" */ //highlight-next-line v_custom_folder varchar2(32767) := :folder;begin /* validate access token to check if it's authorised upload request */ v_access_token := uc_rte_access_token.create_from_token( v_param_accessToken );
if v_access_token.is_valid = 0 then raise_application_error(-20001, 'Invalid access token'); end if;
insert into UC_FROALA_SAMPLE_BLOBS( FILE_NAME, FILE_CONTENT, FILE_MIMETYPE, SESSION_ID, //highlight-next-line FOLDER ) values( v_param_filename, v_image_blob, v_image_mime_type, v_param_sessionId, //highlight-next-line v_custom_folder ) returning ID into v_file_id;
/* Use display URL defined for the plug-in instance */ v_image_link := v_access_token.url_get_image||v_file_id;
/* print JSON to the browser buffer */ apex_json.open_object; apex_json.write('link' , v_image_link, true); apex_json.write('data-image-id', v_file_id , true); apex_json.close_object;
/* set HTTP status code */ :status_code := 200;exception when others then if SQLCODE = -20001 then :status_code := 403;
else :status_code := 500; apex_json.open_object; apex_json.write('error', apex_string.format('While uploading an image, an unexpected error was raised: %s', SQLERRM)); apex_json.close_object;
end if;end;declare v_image_blob blob := :body; v_image_mime_type varchar2(4000) := :content_type; v_image_link varchar2(4000); v_file_id number; v_access_token uc_rte_access_token;
/* default query parameters computed on page load */ v_param_accessToken varchar2(32767) := :accessToken; v_param_filename varchar2(32767) := :filename;
v_checksum varchar2(32767);begin /* validate access token to check if it's authorised upload request */ v_access_token := uc_rte_access_token.create_from_token( v_param_accessToken );
if v_access_token.is_valid = 0 then raise_application_error(-20001, 'Invalid access token'); end if;
insert into UC_FROALA_SAMPLE_BLOBS( FILE_NAME, FILE_CONTENT, FILE_MIMETYPE ) values( v_param_filename, v_image_blob, v_image_mime_type ) returning ID into v_file_id;
// highlight-next-line v_checksum := UC_RTE_ACCESS_TOKEN.encode( v_param_filename||','||v_file_id );
// highlight-next-line v_image_link := v_access_token.url_get_image||v_param_filename||'?checksum='||v_checksum;
/* print JSON to the browser buffer */ apex_json.open_object; apex_json.write('link' , v_image_link, true); apex_json.write('data-image-id', v_file_id , true); apex_json.close_object;
/* set HTTP status code */ :status_code := 200;exception when others then if SQLCODE = -20001 then :status_code := 403;
else :status_code := 500; apex_json.open_object; apex_json.write('error', SQLERRM); apex_json.close_object;
end if;end;Handler Output
Section titled “Handler Output”When an image is saved in the database table, or any other service hosting images, the handler must print to the browser buffer JSON object containing URL displaying uplaoded image and unique image id.
| Property | Type | Description |
|---|---|---|
| data-image-id | VARCHAR2 | The unique id identyfing uplaoded image. The uploaded image id is then stored in the plug-in session state |
| link | VARCHAR2 | The uploaded image URL |
The example JSON might look like in the example below.
{ "data-image-id": "1706", "link": "https://example-domain.com/ords/workspacename/customrest/display/1706"}{ "data-image-id": "1706", "link": "https://example-domain.com/ords/workspacename/customrest/display/1706"}{ "data-image-id": "1706", "link": "https://example-domain.com/ords/workspacename/customrest/display/1706"}{ "data-image-id": "29662", "link": "https://example-domain.com/ords/workspacename/customrest/display-checksum/pngaaa.com-4093606.png?checksum=B41B7A1987DE3A77E6E706C5112805E6713540B7C9F3116646C308428A82EBA9"}:::tip display image link & query parameters
Link to uploaded image can include query parameters that can be used in display handler. See example source code Image checksum.
:::
Error handling
Section titled “Error handling”The plug-in relies on HTTP status code set by the upload handler. Specifying HTTP status code results in display different errror message in the plug-in upload summary.
See sample code below presenting displaying custom error message using HTTP status code 500 and JSON printed to the browser buffer.
begin ...exception when others then :status_code := 500; apex_json.open_object; apex_json.write('error', 'Error message to be displayed in the plug-in upload summary'); apex_json.close_object;end;403 Forbidden
Section titled “403 Forbidden”The plug-in displays following message:
Uplaod handler: 403 Forbidden
404 Not Found
Section titled “404 Not Found”The plug-in displays following message:
Uplaod handler: 404 Not Found.
405 Method Not Allowed
Section titled “405 Method Not Allowed”The plug-in displays following message:
Uplaod handler: 405 Method Not Allowed
500 Internal Sever Error
Section titled “500 Internal Sever Error”If handler result printed JSON with error property, the plug-in display the error property value. Otherwise the plug-in displays the following message:
Uplaod handler raised an error: 500 Internal Server Error (missin “error” property)
555 User Defined Error
Section titled “555 User Defined Error”This HTTP status code is set by ORDS REST when, the upload handler PL/SQL can’t be executed when requested. The plug-in displays following message:
Uplaod handler raised error: 555 User Defined Error
If any other HTTP status code is the result of uplaod handler, the plug-in displays the following message:
Unexpected image upload error