Search code examples
oracleoracle-apexoracle19coracle-apex21.2

Oracle Apex REST response - PDF File not returning correctly


I have an REST API which take a PDF form and the data to fill this pdf form with. In response, pdf form with filled data is returned.

I have tested this API in Postman, work fine.

Now I am making a request with Apex to do the same, following is my code which is executed on page submit.

DECLARE
    lc_response     CLOB;
    l_blob          BLOB;
    lm_multipart    apex_web_service.t_multipart_parts;
    lc_json         CLOB := '[{
    "D1": 194645,
    "R1": 1,
    "R2": 9,
    "R3": 4,
    "R4": 6,
    "R5": 4,
    "R6": 5
    }]';
    lv_filename     VARCHAR2(20) := 'my_file.pdf';
    lv_base_url     VARCHAR2(100) := 'http://10.50.200.11:27005/report'; -- webservice base URL; 
    lv_api_key      VARCHAR2(100); -- API KEY 
    lb_blob         BLOB; -- Blob part of the multipart
    l_dest_offset   PLS_INTEGER := 1;
    l_src_offset    PLS_INTEGER := 1;
    l_lang_context  PLS_INTEGER := dbms_lob.default_lang_ctx;
    l_warning       PLS_INTEGER := dbms_lob.warn_inconvertible_char;
    l_file_mimetype apex_application_files.mime_type%TYPE;
BEGIN

    -- Select unfilled PDF template stored as BLOB in database
    SELECT
        input_template
    INTO lb_blob
    FROM
        python_input_template
    WHERE
        sno = 1;

    apex_web_service.set_request_headers(
                                        p_name_01  => 'x-api-key',
                                        p_value_01 => 'qwerty_key',
                                        p_name_02  => 'x-api-user',
                                        p_value_02 => 'APEX'
    );

    /*Supply data to fill the pdf with*/
    apex_web_service.append_to_multipart(
                                        p_multipart    => lm_multipart,
                                        p_name         => 'data_str',
                                        p_content_type => 'application/json',
                                        p_body         => lc_json
    );
    /*Supply the template to be filled*/
    apex_web_service.append_to_multipart(
                                        p_multipart    => lm_multipart,
                                        p_name         => 'template',
                                        p_filename     => lv_filename,
                                        p_content_type => 'application/pdf',
                                        p_body_blob    => lb_blob
    );

    lc_response := apex_web_service.make_rest_request(
                                                     p_url         => lv_base_url,
                                                     p_http_method => 'POST',
                                                     p_body_blob   => apex_web_service.generate_request_body(lm_multipart)
                   ); 

    /*convert CLOB responce to BLOB*/
    dbms_lob.createtemporary(
                            lob_loc => l_blob,
                            cache   => true
    );
    dbms_lob.converttoblob(
                          dest_lob     => l_blob,
                          src_clob     => lc_response,
                          amount       => dbms_lob.lobmaxsize,
                          dest_offset  => l_dest_offset,
                          src_offset   => l_src_offset,
                          blob_csid    => dbms_lob.default_csid,
                          lang_context => l_lang_context,
                          warning      => l_warning
    );

    sys.htp.init;
    owa_util.mime_header(
                        'application/pdf',
                        false,
                        'UTF-8'
    );
    sys.htp.p('Content-Disposition: attachment; filename="'
              || 'l_file_name.pdf'
              || '"');
    sys.htp.p('Content-length: '
              || sys.dbms_lob.getlength(l_blob));

    sys.owa_util.http_header_close;
    wpg_docload.download_file(l_blob);
    apex_application.stop_apex_engine;
END;

File is getting downloaded but in the file, Only the data that was filled is there, nothing else. So if My pdf template is like

Hi I am pdf template
Form start

Field A <form_field_to_be_filled>

Form End

Then I am only getting following in the generated file




<form_field_to_be_filled>


THIS IS ONLY HAPPENING WHEN MAKING REQUEST IN APEX, NOT IN POSTMAN.

Any ideas?


Solution

  • The APEX_WEB_SERVICE.MAKE_REST_REQUEST returns a CLOB, and for binary content, like a PDF, this can already corrupt data, which cannot be "healed" by converting back to a BLOB again.

    You might use the MAKE_REST_REQUEST_B function, which returns a BLOB directly, then you can even drop your conversion calls.

    l_blob := apex_web_service.make_rest_request_b(
                  p_url         => lv_base_url,
                  p_http_method => 'POST',
                  p_body_blob   => apex_web_service.generate_request_body(lm_multipart) ); 
    
    /* convert CLOB responce to BLOB - not needed any more
    
        dbms_lob.createtemporary(
                                lob_loc => l_blob,
                                cache   => true
        );
        dbms_lob.converttoblob(
                              dest_lob     => l_blob,
                              src_clob     => lc_response,
                              amount       => dbms_lob.lobmaxsize,
                              dest_offset  => l_dest_offset,
                              src_offset   => l_src_offset,
                              blob_csid    => dbms_lob.default_csid,
                              lang_context => l_lang_context,
                              warning      => l_warning
    */