14 KiB
getIcdMmsJson 标准 API 调试文档
1. 文档范围
本文档用于说明 mms-mapping 模块统一调试接口 getIcdMmsJson 的标准调用方式、请求结构、响应规则和联调注意事项。
本文档内容以当前源码为准,主要对照以下实现:
tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingRequestConverter.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingResponseConverter.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/MappingTaskServiceImpl.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingGenerationService.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.javatools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java
说明:
- 本文档仅描述接口契约和调试方式,不改动业务代码。
- 本次未执行
mvn编译、打包或真实接口联调。 - 如文档与运行结果冲突,以源码和实际部署配置为准。
2. 接口基本信息
| 项 | 说明 |
|---|---|
| 接口名称 | getIcdMmsJson |
| 请求方法 | POST |
| 请求路径 | /api/mms-mapping/get-icd-mms-json |
| Content-Type | multipart/form-data |
| 控制器入口 | MappingController#getIcdMmsJson |
| 请求组成 | icdFile 文件 Part + request JSON Part |
| 正常业务响应体 | MappingTaskResponse |
3. 接口职责
该接口是 mms-mapping 模块的统一调试入口,串联以下两个阶段:
- 上传 ICD 文件并完成解析,生成
icdDocument和indexCandidates - 根据
request.indexSelection判断是否继续生成正式mappingJson
接口行为分为三种典型结果:
request.indexSelection未传或为空
返回NEED_INDEX_SELECTION,用于引导前端或调试人员先确认标签与lnInst的绑定关系。request.indexSelection已传但校验不通过
返回NEED_INDEX_SELECTION,同时通过problems给出不合法原因,要求重新选择。request.indexSelection校验通过
返回SUCCESS,输出正式mappingJson,必要时同时落盘并返回savedPath。
补充说明:
- 该接口每次都会重新解析上传的 ICD 文件,因此第二次调试仍然必须重新上传 ICD 文件。
- 该接口正常进入业务编排后,返回体类型为
MappingTaskResponse。 - 如果异常发生在控制器参数绑定或请求转换阶段,例如文件为空、Part 缺失、JSON Part 解析失败,则由全局异常处理器统一包装为
HttpResult<String>,而不是MappingTaskResponse。
4. 请求规范
4.1 multipart/form-data Part 说明
| Part 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
icdFile |
File | 是 | ICD 文件,不能为空 |
request |
JSON Part | 是 | 生成参数,必须按 application/json 发送 |
说明:
requestPart 不能省略。即使第一次只想拿候选结果,也必须传一个最小 JSON。request.indexSelection可以省略或传空数组,此时接口只返回候选结果,不生成正式映射。
4.2 request JSON 结构
{
"version": "2026-04-22",
"author": "debug-user",
"saveToDisk": false,
"prettyJson": true,
"outputDir": "D:/temp/mms-output",
"indexSelection": [
{
"groupKey": "harm",
"groupDesc": "谐波数据",
"bindings": [
{
"reportName": "brcbStHarm",
"dataSetName": "dsStHarm",
"label": "A相",
"lnInst": "1"
}
]
}
]
}
4.3 request 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
version |
String | 否 | 输出版本号。未传或空白时,后端按当天日期补齐,格式为 yyyy-MM-dd |
author |
String | 否 | 作者。未传或空白时,回退到配置项 icd.mapping.default-author,默认值为 system |
saveToDisk |
boolean | 否 | 是否将生成结果写入磁盘 |
prettyJson |
boolean | 否 | 是否输出格式化 JSON。true 为美化 JSON,false 为紧凑 JSON |
outputDir |
String | 否 | 输出目录。未传或空白时,先回退到配置项 icd.mapping.default-output-dir;如果配置也为空,最终落到当前工作目录 |
indexSelection |
Array | 否 | 标签与 lnInst 的最终绑定关系。未传或为空时,只返回候选结果 |
4.4 indexSelection 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
groupKey |
String | 是 | 分组唯一键,必须使用第一次响应里返回的原值 |
groupDesc |
String | 否 | 分组中文描述,便于调试查看 |
bindings |
Array | 是 | 当前业务分组下最终确认的绑定关系列表 |
4.5 bindings 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reportName |
String | 是 | 绑定发生在哪个报告上,例如 brcbStHarm |
dataSetName |
String | 是 | 绑定发生在哪个数据集上,例如 dsStHarm |
label |
String | 是 | 业务标签,例如 A相、最大值、实时数据 |
lnInst |
String | 是 | 标签最终绑定到的逻辑节点实例值,例如 1、2、3 |
5. 标准调试流程
5.1 第一次调试:只获取候选结果
用途:
- 上传 ICD 文件
- 获取
icdDocument - 获取
indexCandidates - 确认每个业务分组下可选的
reportName、dataSetName和availableLnInstValues
调用要求:
requestPart 仍然必须传request.indexSelection可以不传,或传空数组
预期结果:
status = NEED_INDEX_SELECTION- 响应中返回
icdDocument - 响应中返回
indexCandidates
5.2 第二次调试:带索引绑定生成正式结果
用途:
- 根据第一次返回的
indexCandidates组装request.indexSelection - 再次上传同一个 ICD 文件
- 生成正式
mappingJson
调用要求:
- 必须继续上传
icdFile groupKey必须沿用第一次返回值reportName、dataSetName、lnInst必须与第一次返回的候选结果匹配
预期结果:
status = SUCCESS- 响应中返回
mappingJson - 当
saveToDisk = true时,响应中额外返回savedPath
5.3 第二次调试但绑定不合法
适用场景:
groupKey与候选结果不匹配reportName或dataSetName不在候选集中lnInst不在availableLnInstValues内- 绑定关系缺失、不完整或结构错误
预期结果:
status = NEED_INDEX_SELECTION- 响应中仍然返回
icdDocument和indexCandidates problems返回具体问题列表,要求重新确认绑定关系
6. 响应规范
6.1 正常业务响应体
接口正常进入业务编排后,统一返回 MappingTaskResponse。该对象使用了 @JsonInclude(JsonInclude.Include.NON_EMPTY),空字段和空集合不会参与序列化。
基础字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
status |
Enum | 本次处理状态,可能为 SUCCESS、NEED_INDEX_SELECTION、FAILED |
message |
String | 状态说明或错误提示 |
icdDocument |
Object | 需要重新选择索引时返回的 ICD 解析结果 |
mappingJson |
String | 正式生成成功后的映射 JSON 文本 |
savedPath |
String | 结果已落盘时返回的绝对路径 |
indexCandidates |
Array | 待绑定状态下返回的索引候选分组 |
problems |
Array | 模板校验、候选分析或绑定校验问题 |
字段出现规则:
| 状态 | 必有字段 | 可能出现字段 |
|---|---|---|
SUCCESS |
status、message、mappingJson |
savedPath、problems |
NEED_INDEX_SELECTION |
status、message、icdDocument、indexCandidates |
problems |
FAILED |
status、message |
problems |
6.2 NEED_INDEX_SELECTION 响应示例
{
"status": "NEED_INDEX_SELECTION",
"message": "索引配置缺失,请根据候选信息完成标签与数字索引的绑定后重新提交",
"icdDocument": {
"fileName": "demo.icd",
"iedName": "IED1",
"ldInst": "LD0",
"ldPrefix": "LD",
"logicalNodes": [
{
"lnInst": "1"
}
]
},
"indexCandidates": [
{
"groupKey": "harm",
"groupDesc": "谐波数据",
"reportCount": 1,
"templateLabels": [
"A相",
"B相",
"C相"
],
"reports": [
{
"reportName": "brcbStHarm",
"dataSetName": "dsStHarm",
"reportDesc": "谐波报告",
"availableLnInstValues": [
"1",
"2",
"3"
]
}
]
}
]
}
说明:
icdDocument实际字段可能比示例更多。- 如果本次是“索引配置不合法”而不是“索引配置缺失”,通常还会返回
problems。
6.3 SUCCESS 响应示例
{
"status": "SUCCESS",
"message": "映射生成成功",
"mappingJson": "{\n \"version\": \"2026-04-22\",\n \"author\": \"debug-user\",\n \"ied\": \"IED1\",\n \"ld\": \"LD\",\n \"instList\": []\n}"
}
说明:
mappingJson是字符串字段,字段值本身是一段 JSON 文本。- 当
saveToDisk = true时,响应中还会额外返回savedPath。
6.4 FAILED 响应示例
{
"status": "FAILED",
"message": "映射生成失败:加载 DefaultCfg.txt 失败:默认模板文件不存在:template/DefaultCfg.txt",
"problems": [
"加载 DefaultCfg.txt 失败:默认模板文件不存在:template/DefaultCfg.txt"
]
}
说明:
FAILED主要对应服务编排阶段捕获到的运行异常,例如 ICD 解析、模板加载、映射生成、序列化或落盘失败。- 并非所有错误都会进入
FAILED。如果异常发生在控制器参数绑定或请求转换阶段,会走全局异常处理器,而不是这里的业务响应结构。
7. 全局异常响应说明
以下场景通常不会返回 MappingTaskResponse,而是由 GlobalBusinessExceptionHandler 统一包装:
icdFile缺失或为空requestPart 缺失requestPart 的Content-Type不是application/jsonmultipart/form-data结构不合法- JSON 反序列化失败或框架参数绑定失败
这类异常最终会包装为统一的 HttpResult<String> 响应,具体字段结构以全局公共响应定义为准,本文不展开其完整协议,只强调:
- 不能把这类错误等同理解为
MappingTaskResponse.status = FAILED - 联调时应先区分“业务响应体”与“全局异常包装”
8. 调试示例
8.1 curl 示例:第一次调用,只获取候选结果
curl.exe -X POST "http://localhost:8080/api/mms-mapping/get-icd-mms-json" `
-H "Accept: application/json" `
-F 'icdFile=@D:/data/demo.icd' `
-F 'request={"prettyJson":true,"saveToDisk":false};type=application/json'
8.2 curl 示例:第二次调用,带索引绑定直接生成 MMS JSON
curl.exe -X POST "http://localhost:8080/api/mms-mapping/get-icd-mms-json" `
-H "Accept: application/json" `
-F 'icdFile=@D:/data/demo.icd' `
-F 'request={"version":"2026-04-22","author":"debug-user","prettyJson":true,"saveToDisk":false,"indexSelection":[{"groupKey":"harm","groupDesc":"谐波数据","bindings":[{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"A相","lnInst":"1"},{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"B相","lnInst":"2"},{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"C相","lnInst":"3"}]}]};type=application/json'
9. Postman 调试要点
Body选择form-dataicdFile类型选择Filerequest保持文本输入,但该 Part 的Content-Type必须显式设置为application/json- 第一次调试不要省略
requestPart,只是不传indexSelection - 第二次调试时必须继续上传 ICD 文件,并严格按第一次返回的候选结果组装绑定关系
10. 常见问题
10.1 为什么第一次调试也必须传 request
因为控制器方法签名使用的是 @RequestPart("request") GenerateMappingFromIcdRequest request,该 Part 本身就是必填参数。第一次调试可以只传最小 JSON,但不能完全省略。
10.2 为什么没有传 indexSelection,却没有返回 FAILED
这是接口设计的正常行为。indexSelection 缺失或为空时,业务语义不是“接口执行失败”,而是“还需要前端继续确认索引绑定”,因此返回的是 NEED_INDEX_SELECTION。
10.3 saveToDisk=true 但没有传 outputDir,结果会保存到哪里
处理顺序如下:
- 先读取请求中的
outputDir - 如果请求空白,则回退到配置项
icd.mapping.default-output-dir - 如果配置项也为空,则最终落到当前工作目录
10.4 version 不传时会变成什么
后端在正式生成映射文档时,会把空白 version 自动补成当天日期,格式为 yyyy-MM-dd。
10.5 mappingJson 为什么是字符串,不是嵌套对象
因为当前响应结构中 mappingJson 定义为 String,接口返回的是一段已经序列化好的 JSON 文本,而不是再次展开后的对象结构。
10.6 什么情况下会返回 problems
problems 主要用于承载以下问题:
- 默认模板校验问题
- 索引候选分析问题
indexSelection绑定校验问题- 服务编排阶段捕获到的异常原因
11. 当前边界
- 当前文档仅覆盖
getIcdMmsJson接口,不覆盖get-icd与get-mms-json的独立接口文档 - 当前文档重点描述业务返回体与调试方式,不展开全局
HttpResult的完整协议 - 示例中的
icdDocument、indexCandidates和mappingJson为结构化示意,实际字段数量与内容以运行结果为准