import ChangeLog from ‘../changelog/connector-http.md’;
Http 源连接器
Spark
Flink
SeaTunnel Zeta
用于从 Http 读取数据。
为了使用 Http 连接器,需要以下依赖项。 可以通过 install-plugin.sh 或从 Maven 中央仓库下载。
| 数据源 | 支持的版本 | 依赖 |
|---|---|---|
| Http | 通用 | 下载 |
| 名称 | 类型 | 是否必须 | 默认值 | 描述 |
|---|---|---|---|---|
| url | String | 是 | - | Http 请求 URL。 |
| schema | Config | 否 | - | Http 和 seatunnel 数据结构映射。更多详情请参考 Schema 特性。 |
| schema.fields | Config | 否 | - | 上游数据的 schema 字段 |
| json_field | Config | 否 | - | 此参数帮助您配置 schema,因此此参数必须与 schema 一起使用。 |
| pageing | Config | 否 | - | 此参数用于分页查询 |
| pageing.page_field | String | 否 | - | 此参数用于指定请求中的页面字段名称。它可以在 headers、params 或 body 中使用占位符,如 ${page_field}。 |
| pageing.use_placeholder_replacement | Boolean | 否 | false | 如果为 true,则使用占位符替换(${field})用于 headers、parameters 和 body 值,否则使用基于键的替换。 |
| pageing.total_page_size | Int | 否 | - | 此参数用于控制总页数 |
| pageing.batch_size | Int | 否 | - | 每个请求返回的批量大小,用于在总页数未知时确定是否继续 |
| pageing.start_page_number | Int | 否 | 1 | 指定同步开始的页码 |
| pageing.page_type | String | 否 | PageNumber | 此参数用于指定页面类型,如果未设置则为 PageNumber,仅支持 PageNumber 和 Cursor。 |
| pageing.cursor_field | String | 否 | - | 此参数用于指定请求参数中的游标字段名称。 |
| pageing.cursor_response_field | String | 否 | - | 此参数指定从中检索游标的响应字段。 |
| content_field | String | 否 | - | 此参数可以获取一些 json 数据。如果您只需要 ‘book’ 部分的数据,配置 content_field = "$.store.book.*"。 |
| format | String | 否 | text | 上游数据的格式,支持 json text binary,默认为 text。当设置为 binary 时,响应体作为原始字节处理,用于下载文件(PDF、图片、ZIP 等)。 |
| binary_chunk_size | Long | 否 | 10485760 | 当 format = binary 时的分片大小(字节)。大文件会被拆分为多行。默认 10MB。仅在 BATCH 模式下生效。 |
| method | String | 否 | get | Http 请求方法,仅支持 GET、POST 方法。 |
| headers | Map | 否 | - | Http 头信息。 |
| params | Map | 否 | - | Http 参数。 |
| body | String | 否 | - | Http 请求体,程序将自动添加 http header application/json,body 是 jsonbody。 |
| poll_interval_millis | Int | 否 | - | 流模式下请求 http api 的间隔(毫秒)。 |
| retry | Int | 否 | - | 如果请求 http 返回 IOException 的最大重试次数。 |
| retry_backoff_multiplier_ms | Int | 否 | 100 | 请求 http 失败时的重试退避时间(毫秒)乘数。 |
| retry_backoff_max_ms | Int | 否 | 10000 | 请求 http 失败时的最大重试退避时间(毫秒) |
| enable_multi_lines | Boolean | 否 | false | |
| connect_timeout_ms | Int | 否 | 12000 | 连接超时设置,默认 12 秒。 |
| socket_timeout_ms | Int | 否 | 60000 | Socket 超时设置,默认 60 秒。 |
| common-options | 否 | - | 源插件通用参数,请参考 Source Common Options 获取详细信息 | |
| keep_params_as_form | Boolean | 否 | false | 是否按照表单提交参数,用于兼容旧行为。当为 true 时,params 参数的值通过表单提交。 |
| keep_page_param_as_http_param | Boolean | 否 | false | 是否将分页参数设置为 params。用于兼容旧行为。 |
| json_filed_missed_return_null | Boolean | 否 | false | 当 JSON 字段缺失时,设置为 true 并返回 null,否则返回错误。 |
env { parallelism = 1 job.mode = "BATCH" } source { Http { plugin_output = "http" url = "http://mockserver:1080/example/http" method = "GET" format = "json" schema = { fields { c_map = "map<string, string>" c_array = "array<int>" c_string = string c_boolean = boolean c_tinyint = tinyint c_smallint = smallint c_int = int c_bigint = bigint c_float = float c_double = double c_bytes = bytes c_date = date c_decimal = "decimal(38, 18)" c_timestamp = timestamp c_row = { C_MAP = "map<string, string>" C_ARRAY = "array<int>" C_STRING = string C_BOOLEAN = boolean C_TINYINT = tinyint C_SMALLINT = smallint C_INT = int C_BIGINT = bigint C_FLOAT = float C_DOUBLE = double C_BYTES = bytes C_DATE = date C_DECIMAL = "decimal(38, 18)" C_TIMESTAMP = timestamp } } } } } # 控制台打印读取的 Http 数据 sink { Console { parallelism = 1 } }
当您指定 format 为 json 时,您还应该指定 schema 选项,例如:
上游数据如下:
{ "code": 200, "data": "get success", "success": true }
您应该指定 schema 如下:
schema { fields { code = int data = string success = boolean } }
连接器将生成如下数据:
| code | data | success |
|---|---|---|
| 200 | get success | true |
当您指定 format 为 text 时,连接器不会对上游数据做任何处理,例如:
上游数据如下:
{ "code": 200, "data": "get success", "success": true }
连接器将生成如下数据:
| content |
|---|
| {“code”: 200, “data”: “get success”, “success”: true} |
当您指定 format 为 binary 时,HTTP 响应体作为原始字节处理,用于下载文件(PDF、图片、ZIP 等)。输出 schema 固定为 (data: bytes, relativePath: string, partIndex: long)。大文件会根据 binary_chunk_size 自动拆分为多行。仅支持 BATCH 模式,且不支持分页(pageing)。
示例:通过 HTTP 下载文件并写入 LocalFileSink:
env { parallelism = 1 job.mode = "BATCH" } source { Http { url = "http://example.com/files/report.pdf" method = "GET" format = "binary" binary_chunk_size = 10485760 # 每个分片 10MB schema = { fields { data = bytes relativePath = string partIndex = long } } } } sink { LocalFile { path = "/tmp/download" file_format = "binary" } }
为了兼容旧版本的 http。 当设置为 true 时,<params> 和 <pageing> 将以表单形式提交。 当设置为 false 时,<params> 将添加到 url 路径中,而 <pageing> 不会添加到 body 或表单中。它将替换 params 和 body 中的占位符。
是否将分页参数设置为 params。 当设置为 true 时,<pageing> 设置为 <params>。 当设置为 false 时,当页面字段存在于 <body> 或 <params> 中时,替换值。
当设置为 false 时,配置示例:
body="""{"id":1,"page":"${page}"}"""
params={ page: "${page}" }
默认情况下,参数将添加到 url 路径中。 如果您需要保持旧版本行为,请检查 keep_params_as_form。
HTTP body 用于在请求或响应中携带实际数据,包括 JSON、表单提交。
参考格式如下:
body="{"id":1,"name":"seatunnel"}"
对于表单提交,请按如下设置 content-type。
headers { Content-Type = "application/x-www-form-urlencoded" }
下面几条规则最容易混淆,建议先按“最终发出的 HTTP 请求长什么样”来理解:
GET 请求:params 一定会被拼到 URL 查询串里。POST 且 keep_params_as_form = false:params 仍然会拼到 URL 查询串里body 会作为 JSON body 发送body,并且请求仍然走这个默认非 form 分支,运行时会发送一个空 JSON 对象 {} 作为请求体Content-Type 设为 application/x-www-form-urlencoded,运行时会改走 form-body 分支,而不是默认 JSON 分支POST 且 keep_params_as_form = true:params 会并入表单 bodyContent-Type,SeaTunnel 会自动补 application/x-www-form-urlencodedbody 与 params 出现同名键,params 的值会覆盖 body 中同名键keep_page_param_as_http_param = true:分页字段会直接写入 paramskeep_page_param_as_http_param = false:SeaTunnel 只会更新 headers、params、body 里已经存在的同名键或占位符,不会凭空新增分页字段pageing.use_placeholder_replacement = true:支持 ${page}、${cursor} 占位符,也支持 "10${page}" -> "105" 这种带前后缀的替换;为 false 时只做按 key 的整值替换示例 1:GET 分页,页码写入查询参数
source { Http { url = "https://api.example.com/orders" method = "GET" params = { page = "${page}" size = "100" } pageing = { page_field = "page" page_type = "PageNumber" start_page_number = 3 use_placeholder_replacement = true } } }
当页码推进到 3 时,最终请求为:
GET https://api.example.com/orders?page=3&size=100
示例 2:POST JSON(默认非 form 分支),请求参数进 URL,分页字段留在 body
source { Http { url = "https://api.example.com/orders/search" method = "POST" keep_params_as_form = false params = { tenant = "acme" } body = """{"page":"${page}","pageSize":100}""" pageing = { page_field = "page" page_type = "PageNumber" start_page_number = 3 use_placeholder_replacement = true } } }
当页码推进到 3 时,最终请求为:
POST https://api.example.com/orders/search?tenant=acme Content-Type: application/json Body: {"page":"3","pageSize":100}
示例 3:POST 表单,请求参数和分页字段都写入表单 body
source { Http { url = "https://api.example.com/orders/search" method = "POST" keep_params_as_form = true keep_page_param_as_http_param = true params = { size = "100" } pageing = { page_field = "page" page_type = "PageNumber" start_page_number = 3 } } }
当页码推进到 3 时,最终请求为:
POST https://api.example.com/orders/search Content-Type: application/x-www-form-urlencoded Body: size=100&page=3
此参数可以获取一些 json 数据。如果您只需要 ‘book’ 部分的数据,配置 content_field = "$.store.book.*"。
如果您的返回数据看起来像这样。
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ], "bicycle": { "color": "red", "price": 19.95 } }, "expensive": 10 }
您可以配置 content_field = "$.store.book.*" 并且返回的结果看起来像这样:
[ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ]
然后您可以使用更简单的 schema 获取所需的结果,如
Http { url = "http://mockserver:1080/contentjson/mock" method = "GET" format = "json" content_field = "$.store.book.*" schema = { fields { category = string author = string title = string price = string } } }
这里是一个示例:
此参数帮助您配置 schema,因此此参数必须与 schema 一起使用。
如果您的数据看起来像这样:
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ], "bicycle": { "color": "red", "price": 19.95 } }, "expensive": 10 }
您可以通过如下配置任务来获取 ‘book’ 的内容:
source { Http { url = "http://mockserver:1080/jsonpath/mock" method = "GET" format = "json" json_field = { category = "$.store.book[*].category" author = "$.store.book[*].author" title = "$.store.book[*].title" price = "$.store.book[*].price" } schema = { fields { category = string author = string title = string price = string } } } }
当前支持的分页类型是 PageNumber 和 Cursor。 如果您需要使用分页,您需要配置 pageing。默认分页类型是 PageNumber。
使用 PageNumber 分页时,您可以在 HTTP 请求的不同部分包含页面参数:
params 部分body JSON 中包含页面参数headers 部分您可以使用占位符如 ${page} 与 use_placeholder_replacement = true 来动态更新这些值。占位符可以以各种格式使用:
"${page}""10${page}" 或 "page-${page}"${page}(在 JSON 体中){"pagination":{"page":${page}}}source { Http { url = "http://localhost:8080/mock/queryData" method = "POST" format = "json" body="""{"id":1,"page":"${page}"}""" content_field = "$.data.*" params={ page: "${page}" } pageing={ #你可以不设置此参数,默认值是 PageNumber page_type="PageNumber" total_page_size=20 page_field=page use_placeholder_replacement=true #当不知道 total_page_size 时使用 batch_size,如果读取大小<batch_size 则完成,否则继续 #batch_size=10 } schema = { fields { name = string age = string } } } }
source { Http { url = "http://localhost:8080/mock/queryData" method = "GET" format = "json" headers={ Page-Number = "${pageNo}" Authorization = "Bearer token-123" } pageing={ page_field = pageNo start_page_number = 1 batch_size = 10 use_placeholder_replacement = true } schema = { fields { name = string age = string } } } }
source { Http { url = "http://localhost:8080/mock/queryData" method = "GET" format = "json" params={ page = "1" } pageing={ page_field = page start_page_number = 1 batch_size = 10 use_placeholder_replacement = false } schema = { fields { name = string age = string } } } }
source { Http { url = "http://localhost:8080/mock/queryData" method = "GET" format = "json" headers = { Page-Number = "10${page}" # 当 page=5 时将变为 "105" Authorization = "Bearer token-123" } pageing = { page_field = page start_page_number = 5 batch_size = 10 use_placeholder_replacement = true } schema = { fields { name = string age = string } } } }
source { Http { url = "http://localhost:8080/mock/queryData" method = "POST" format = "json" body = """{"a":${page},"limit":10}""" # 不带引号的数字 pageing = { page_field = page start_page_number = 1 batch_size = 10 use_placeholder_replacement = true } schema = { fields { name = string age = string } } } }
source { Http { url = "http://localhost:8080/mock/queryData" method = "POST" format = "json" body = """{"pagination":{"page":${page},"size":10},"filters":{"active":true}}""" # 嵌套结构 pageing = { page_field = page start_page_number = 1 total_page_size = 20 use_placeholder_replacement = true } schema = { fields { name = string age = string } } } }
pageing.page_type 参数必须设置为 Cursor。 cursor_field 是请求参数中游标的字段名称。 cursor_response_field 是响应数据中分页令牌字段的名称,我们应该将其添加到请求的分页字段中。
source { Http { plugin_output = "http" url = "http://localhost:8080/mock/cursor_data" method = "GET" format = "json" content_field = "$.data.*" keep_page_param_as_http_param = true pageing ={ page_type="Cursor" cursor_field ="cursor" cursor_response_field="$.paging.cursors.next" } schema = { fields { content=string id=int name=string } } json_field = { content = "$.data[*].content" id = "$.data[*].id" name = "$.data[*].name" } } }