REST 端口如何识别 200 OK 中的业务失败并自动重试
© All rights reserved. • 西安知行软件有限公司 • 陕ICP备09022277号
一、适用场景
在 REST 接口对接中,HTTP 状态码表示的是 HTTP 请求的处理结果,并不一定等同于业务处理结果。部分业务系统即使处理失败,仍会返回:
HTTP/1.1 200 OK
然后通过响应体表达业务失败,例如:
<Status>failed</Status>
或:
{
"status": "failed",
"message": "库存不足"
}
如果 REST 端口只根据 HTTP 状态码判断请求结果,这类响应会被识别为成功,自动重试也不会触发。对于订单、库存、发票、出库单等业务,这可能造成“对方实际处理失败,但知行之桥侧显示发送成功”的状态不一致。
本文将通过一个本地测试流程,完整演示如何实现:
- 使用
Webhook1模拟接口返回 HTTP200 OK。 - 在响应体中返回
<Status>failed</Status>。 - 使用
REST2的 Response 事件读取_response.body。 - 识别业务失败后使用
arc:throw抛出错误。 - 将响应事件错误行为设置为
Fail。 - 开启发送自动化,使失败请求按照重试参数再次发送。
二、测试实现链路
测试处理链路如下:
上传测试文件到 REST2
↓
REST2 通过 POST 调用 Webhook1
↓
Webhook1 返回 HTTP 200 OK
↓
响应体返回 <Status>failed</Status>
↓
REST2 Response 事件读取 _response.body
↓
检测到 failed 后执行 arc:throw
↓
响应事件错误行为 Fail 将本次尝试判定为失败
↓
发送自动化按照重试间隔和最大次数继续尝试
这里需要区分两个验证目标:
- 业务失败识别验证:证明 REST2 能把
200 OK + failed转换成失败。 - 自动重试验证:证明开启发送自动化后,同一消息会按照重试间隔再次调用 Webhook1。
三、参考环境与版本检查
本文示例参考环境:
| 项目 | 示例值 |
|---|---|
| 产品版本 | 知行之桥 Java 版 26.2.9645.0 |
| 工作区 | TEST |
| REST 端口 | REST2 |
| Webhook 端口 | Webhook1 |
| 调用方法 | POST |
| Webhook 路径 | /connector/TEST/Webhook1/webhook.rsb |
示例工作区如下:

截图中的 REST2 显示“自动发送未启用”,因此该截图只用于展示测试环境。要验证自动重试,后续必须在 REST2 的自动化页面开启“发送”。
检查版本是否支持响应事件错误行为
打开:
REST2 > 高级设置
确认页面中存在:
响应事件错误行为
该设置用于决定 Response 事件抛出异常后,REST 端口应将其处理为失败、警告还是继续成功。
如果当前 REST 端口中没有该设置,请先确认版本和端口类型。
四、配置 Webhook1:模拟 200 OK 中的业务失败
1. 创建 Webhook 端口
在 TEST 工作区中新建 Webhook 端口:
端口 ID:Webhook1
REST2 是通过 HTTP URL 调用 Webhook1,因此两者不需要通过工作流连线连接。
2. 配置测试用户和访问权限
进入 Webhook1 的 用户 页面:
- 新建一个测试用户。
- 为用户开启
POST权限。 - 保存系统生成的
Authtoken,后续配置 REST2 时需要使用。
进入 Webhook1 的 服务器 页面:
- 将
127.0.0.1加入受信任 IP。 - 如果本机通过 IPv6 解析 localhost,同时加入
::1。
如果用户权限、Authtoken 或受信任 IP 配置不正确,REST2 可能收到 401 或 403。这属于身份验证失败,并不是本文要模拟的“HTTP 200 中的业务失败”。
3. 配置 Webhook1 的 Response 事件
进入:
Webhook1 > 事件 > Response
配置脚本:
<arc:set attr="_response.header:Content-Type" value="application/xml" />
<arc:set attr="_response.statuscode" value="200" />
<arc:set attr="_response.statusdescription" value="OK" />
<arc:set attr="_response.write" value="<Status>failed</Status>" />

各行脚本的作用如下:
| 脚本 | 作用 |
|---|---|
_response.header:Content-Type |
将响应内容类型设置为 XML |
_response.statuscode |
显式返回 HTTP 状态码 200 |
_response.statusdescription |
将 HTTP 状态描述设置为 OK |
_response.write |
写入自定义响应体 |
保存后,Webhook1 收到 POST 请求时将返回:
HTTP/1.1 200 OK
Content-Type: application/xml
<Status>failed</Status>
这样就模拟出了“HTTP 调用成功,但业务处理失败”的接口行为。
五、配置 REST2:调用 Webhook1
1. 创建并配置 REST 端口
在同一工作区中新建 REST 端口:
| 设置 | 示例值 |
|---|---|
| 端口 ID | REST2 |
| 操作类型 | 终结 |
| 请求方法 | POST |
| 正文类型 | raw |
| Content-Type | application/xml |
REST2 的请求 URL 使用下面的格式:
http://localhost:端口号/connector/工作区/Webhook端口ID/webhook.rsb
例如知行之桥本地端口为 12501,工作区为 TEST:
http://localhost:12501/connector/TEST/Webhook1/webhook.rsb
请根据实际环境替换端口号、工作区名称和 Webhook 端口 ID。
2. 配置 Webhook 身份验证
在 REST2 的请求头中添加 Webhook1 测试用户的 Authtoken。常见形式为:
x-cdata-authtoken: Webhook1中生成的Authtoken
3. 先使用“测试”检查 HTTP 调用
完成 URL、方法、请求头和正文配置后,可以先点击 REST2 的 测试 按钮。
正确结果应同时满足:
HTTP/1.1 200 OK
响应正文为:
<Status>failed</Status>
如果返回 401 或 403,依次检查:
- Authtoken 是否正确。
- Webhook 用户是否拥有 POST 权限。
127.0.0.1或::1是否已加入受信任 IP。- URL 中的工作区、端口 ID 和服务端口是否正确。
REST 端口的“测试”功能不会创建正常的工作流消息或交易,适合验证 URL、身份验证和响应内容,但不能用于验证发送自动化和自动重试。
六、配置 REST2 的 Response 事件
进入:
REST2 > 事件 > Response
配置脚本:
<arc:set attr="response.text" value="[_response.body]" />
<arc:if exp="[response.text | contains('failed')]">
<arc:throw
code="BusinessFailure"
desc="接口返回 failed,REST 端口将本次请求判定为失败。" />
</arc:if>

脚本说明:
| 脚本片段 | 作用 |
|---|---|
_response.body |
获取 REST 服务返回的响应体 |
response.text |
保存响应体的自定义变量 |
contains('failed') |
演示环境中判断响应体是否包含 failed |
arc:throw |
主动抛出异常 |
code="BusinessFailure" |
设置便于识别的业务错误码 |
desc |
写入交易日志中的错误说明 |
演示判断与生产判断的区别
本文为了方便复现,使用全文包含判断:
contains('failed')
这种写法可能误判,例如响应消息中出现“previous request failed, current request success”。生产环境应解析明确的业务字段:
- JSON:解析
status、success或code。 - XML:解析
/Status或/Result/Code。
REST 官方示例使用 _response.body 取得正文,并使用 jsonDOMGet 解析 JSON;XML 响应可以使用 xmlDOMGet 实现同类处理。
七、设置响应事件错误行为
进入:
REST2 > 高级设置
将 响应事件错误行为设置为:
Fail

三个选项的区别如下:
| 响应事件错误行为 | Response 事件抛错后的结果 | 是否用于本场景 |
|---|---|---|
Fail |
REST 操作失败,可以进入失败重试逻辑 | 是 |
Warn |
REST 操作不失败,但记录警告 | 否 |
Continue |
REST 操作继续成功,不记录为失败事务 | 否 |
仅配置 arc:throw 还不够。如果选择 Warn 或 Continue,端口不会将该次发送认定为失败,也就不能按失败发送逻辑进行自动重试。
八、开启发送自动化和重试
进入:
REST2 > 自动化
为了快速完成本地测试,建议先配置:
| 设置 | 测试值 | 说明 |
|---|---|---|
| 发送 | 开启 | 自动处理进入 REST2 的待发送消息 |
| 重试间隔 | 1 分钟 | 每次失败后等待 1 分钟再次尝试 |
| 最大次数 | 3 | 首次发送和后续尝试合计最多 3 次 |
最大次数包含首次发送:
- 设置为
1:只发送一次,不重试。 - 设置为
3:首次发送失败后,最多再尝试两次。 - 设置为
5:所有发送尝试合计最多五次。
九、触发正式测试
不要继续使用 REST2 的“测试”按钮。进入 REST2 的 交易页面,上传一个测试文件,例如:
<TestRequest>
<Id>retry-001</Id>
</TestRequest>
如果 REST2 的正文类型为 raw,该文件内容会作为 POST 请求正文发送给 Webhook1。
首次请求的预期过程:
- REST2 向 Webhook1 发送 POST。
- Webhook1 返回 HTTP
200 OK。 - Webhook1 的响应体为
<Status>failed</Status>。 - REST2 Response 事件读取
_response.body。 contains('failed')返回 true。arc:throw抛出BusinessFailure。Fail将本次发送尝试认定为失败。- 发送自动化等待 1 分钟后再次发送。
- 达到最大次数仍失败时,消息最终进入 Error。
十、验证业务失败识别结果
REST2 的发送日志中应先看到 HTTP 层返回成功:
HTTP/1.1 200 OK

响应大小为 23 Bytes,对应:
<Status>failed</Status>
随后 Response 事件抛出错误,页面和交易详情中可以看到配置的错误说明:


这些截图能够证明:REST2 没有把 200 OK 直接当成业务成功,而是根据响应体把发送结果转换成了失败。
完成上述配置后,REST 端口就可以从“只判断 HTTP 成功或失败”升级为“同时判断业务成功或失败”。即使接口返回 200 OK,只要响应体表明业务失败,REST 端口也会将本次尝试判定为失败,并按照自动化配置执行后续重试。
十一、常见问题
1. 为什么 HTTP 200 OK 还要抛错?
因为 HTTP 状态和业务状态属于两个层次。HTTP 200 表示请求在 HTTP 层获得成功响应;如果响应体中包含 failed、success=false 或业务错误码,仍然可能代表业务失败。
2. 为什么 REST 测试按钮成功,但上传文件后失败?
测试按钮只验证当前请求配置。上传文件会进入正常交易处理过程,同时执行 Response 事件和错误行为设置,因此可能出现“HTTP 测试成功,但业务校验失败”的结果,这正是本文要实现的效果。
3. 为什么脚本抛错后没有自动重试?
重点检查:
- 响应事件错误行为是否为
Fail。 - REST2 的发送自动化是否开启。
- 最大次数是否大于
1。 - 重试间隔是否已经到达。
- 是否使用正常交易上传文件,而不是只点击测试按钮。
4. 为什么返回 401 或 403?
这通常不是业务失败脚本造成的,而是 Webhook 访问控制问题。检查 Authtoken、POST 权限和受信任 IP。


