下载 BLOB 文件时编码错误

Encoding error when downloading BLOB File

因此,我目前正在尝试下载存储在 Oracle table 中的 xml 文件以及我为 Oracle Apex 页面创建的 link。这是设置:

table 可以包含 2 个不同的文件 xml 存储为 blob。因此,我试图在 Oracle Apex 上生成一份报告,其中包含 link 以下载这些 blob,每行数据对应每种类型的文件。

我必须设置 links 的查询如下:

select max(case when a.filename like 'TYPE1%' then dbms_lob.getlength(a.upload_file) else null end) as upload_type1,
       max(case when a.filename like 'TYPE2%' then dbms_lob.getlength(a.upload_file) else null end) as upload_type2
from blob_table a;

现在页面报告应该有 2 列,每一列都有不同的 link,设置为每一列的大小。 link 本身分别使用 "Type1" 和 "Type2" 作为请求设置到同一页面,这意味着触发以下 PLSQL 函数来下载文件:

declare

  l_blob_content blob_table.upload_file%TYPE;
  l_mime_type    varchar2(20);
  l_id           number;
  l_filename     varchar2(255);

begin

    select id
    into l_id
    from blob_table
    where file_id = :FILE_ID
    and filename like 'TYPE1%';

    select upload_file
           ,'text/xml',
           filename
    into   l_blob_content,
           l_mime_type,
           l_filename
    from   blob_table
    where  id = l_id;

    sys.HTP.init;
    sys.OWA_UTIL.mime_header(l_mime_type, FALSE, 'UTF-8');
    sys.HTP.p('Content-Length: ' || DBMS_LOB.getlength(l_blob_content));
    sys.HTP.p('Content-Disposition: filename="' || l_filename || '"');
    sys.OWA_UTIL.http_header_close;

    sys.WPG_DOCLOAD.download_file(l_blob_content);
    apex_application.stop_apex_engine;
    exception when  apex_application.e_stop_apex_engine then
        null;
    when others then
        HTP.p('Something wrong');
end;

到目前为止,与我在搜索此功能时看到的情况相比,一切似乎都已到位。但是,当我单击 link 并尝试下载它时,我收到的消息是:

一开始以为我哪里不对,也测试了mime_type为"application/xml",页面显示的文件是HTML格式。 "text/xml" 给出编码错误的任何想法?它与 mime_type 的第 3 个输入值有关吗?

有几件事似乎不对。

  1. 错误消息 "Encoding error" 来自哪里?是编辑的吗?它看起来不像是 Oracle 错误消息。
  2. 您的 XML 文档是否真正存储为二进制 LOB?如果是这样,您确定数据编码是真正的 utf-8 吗?你是如何验证的?

'application/xml' 可能是正确的 mime_type。您的 Content-Disposition 是错误的。您是要下载文件还是要在浏览器中显示文件?如果您想在浏览器中显示它,请使用以下内容:

sys.HTP.p('Content-Disposition: inline');

如果要下载文件,请使用以下命令:

sys.HTP.p('Content-Disposition: attachment; filename="' || l_filename || '"');

此外,我不确定它是何时添加的,但在 APEX v20.1 中,应用程序库中有一个示例文件上传和下载应用程序,您可以使用它来了解如何以声明方式完成此操作。