You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PL/SQL向Web服务发送multipart/form-data格式图片并添加参数

问题修正与参数添加方案

一、现有代码的已知问题修正

你当前的代码存在逻辑错误,会导致请求体格式异常:

  • 你已经将图片转成Base64写入了p_request_body,后续又把原始二进制图片l_attachment追加到blb中,相当于重复提交了两次图片数据,格式完全不符合multipart规范,这是你请求异常的核心原因之一
  • 重复设置了Content-Type请求头,多余的设置可以直接删除

二、添加请求参数的方法

1. 添加URL查询参数(对应你Postman示例中的subject=56543参数)

直接修改p_url变量,把参数拼接到URL末尾即可,示例:

-- 原p_url修改为带查询参数的格式
p_url VARCHAR2(255) := 'http://192.168.0.120:8000/api/v1/recognition/faces?subject=56543';

如果参数是动态值,用字符串拼接即可,注意特殊字符要做URL转义,可调用utl_url.escape()函数处理参数值。

2. 添加multipart/form-data普通表单参数

如果参数需要放在请求体的form字段里,直接在p_request_body的文件字段前面追加普通字段的multipart结构即可,示例:

p_request_body := l_newline || '--' || lco_boundary || l_newline ||
                  -- 普通表单参数subject
                  'Content-Disposition: form-data; name="subject"' || l_newline || l_newline ||
                  '56543' || l_newline ||
                  -- 原有文件字段
                  '--' || lco_boundary || l_newline ||
                  'Content-Disposition: form-data; name="file"; filename="' ||
                  l_file_name || '"' || l_newline || 'Content-Type: ' ||
                  l_mime_type || l_newline ||
                  'Content-Transfer-Encoding: base64' || l_newline ||
                  l_newline ||
                  apex_web_service.blob2clobbase64(l_attachment) ||
                  l_newline || '--' || lco_boundary || '--';

注意:这里把chunked改成了base64,和实际的图片编码格式保持一致。

三、修正后核心代码片段

删掉多余的dbms_lob.append(blb, l_attachment);语句,因为你已经把Base64编码的图片写入到p_request_body里了,不需要再追加原始二进制图片:

-- 原有converttoblob之后直接删除append语句
dbms_lob.createtemporary(blb, FALSE);
dest_offset  := 1;
src_offset   := 1;
lang_context := 0;
dbms_lob.converttoblob(blb,
                       p_request_body,
                       dbms_lob.getlength(p_request_body),
                       dest_offset,
                       src_offset,
                       0,
                       lang_context,
                       warning);
-- 删掉这行:dbms_lob.append(blb, l_attachment);
req_length := dbms_lob.getlength(blb);

-- 删掉多余的第一个Content-Type设置
-- utl_http.set_header(utl_req, 'content-type', 'multipart/form-data'); 该设置重复,下方已有带boundary的正确设置

四、可选简化方案

你使用的是APEX 21.1,可以直接调用原生的apex_web_service.make_rest_request接口发送multipart请求,不需要手动拼接边界和编码,代码更简洁不易出错:

DECLARE
  l_response CLOB;
  l_attachment BLOB;
  l_file_name VARCHAR2(255);
  l_mime_type VARCHAR2(255);
BEGIN
  SELECT IMAGE, FILENAME, MIMETYPE
    INTO l_attachment, l_file_name, l_mime_type
    FROM TEST_TABLE
   WHERE ID_ID = 21;

  -- 设置请求头
  apex_web_service.g_request_headers.delete();
  apex_web_service.g_request_headers(1).name := 'x-api-key';
  apex_web_service.g_request_headers(1).value := 'ce83481a-701f-xxxx-a3ec-exxxxxb5665e';

  -- 发送请求,自动处理multipart格式
  l_response := apex_web_service.make_rest_request(
    p_url => 'http://192.168.0.120:8000/api/v1/recognition/faces?subject=56543',
    p_http_method => 'POST',
    p_body_blob => l_attachment,
    p_body_blob_mime_type => l_mime_type,
    p_body_blob_parameter_name => 'file',
    p_body_blob_filename => l_file_name
  );

  -- 输出响应
  dbms_output.put_line('响应状态:'||apex_web_service.g_status_code);
  dbms_output.put_line('响应内容:'||l_response);
END;
/

内容的提问来源于stack exchange,提问作者Amit Dabhekar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:39:00