Go Template映射SOAP转JSON异常问题(基于Krakend插件)
问题分析与修复方案
核心问题
从错误日志和模板代码来看,导致JSON解析失败的原因有三个:
- 非法的JSON字符:模板中使用了HTML转义实体
"代替原生双引号",生成的内容不是合法的JSON格式,解析器无法识别。 - 字段末尾多余逗号:当没有
promotionBundleId和promotionServiceId时,description字段后的逗号会导致JSON对象最后出现无效的 trailing comma。 - 空数组判断逻辑不严谨:直接用
{{if .promotionData.promotionBundleId}}会匹配空切片(非nil),若数组无元素仍会生成字段;同时若输入为单个值而非数组,range会遍历字符串字符导致错误。
修复后的模板代码
{{if .promotionData}} "promotionData": { "identifier": "{{.promotionData.identifier}}", "description": "{{.promotionData.description}}" {{- /* 处理promotionBundleId:仅当数组有元素时生成字段 */}} {{- if gt (len .promotionData.promotionBundleId) 0}} ,"promotionBundleId": [ {{- range $index, $id := .promotionData.promotionBundleId -}} {{- if $index}},{{end}}"{{ $id }}"{{- end -}} ] {{- end}} {{- /* 处理promotionServiceId:仅当数组有元素时生成字段 */}} {{- if gt (len .promotionData.promotionServiceId) 0}} ,"promotionServiceId": [ {{- range $index, $ele := .promotionData.promotionServiceId -}} {{- if $index}},{{end}}"{{ $ele }}"{{- end -}} ] {{- end}} } {{else}} "promotionData": [] {{end}}
关键修复点说明
- 替换
"为":直接输出JSON标准的双引号,确保生成的内容是可解析的JSON格式。 - 调整逗号位置:将可选字段的逗号放在字段开头(
,"promotionBundleId": ...),仅当存在可选字段时才添加逗号,彻底避免trailing comma问题。 - 精确判断数组非空:使用
{{if gt (len .promotionData.promotionBundleId) 0}}判断数组是否包含元素,仅在有元素时生成对应字段;若需要保留空数组字段(如字段存在但无元素时生成"promotionBundleId": []),可将判断改为{{if .promotionData.promotionBundleId}}。
额外优化:支持单个值转数组
若输入的promotionBundleId或promotionServiceId可能是单个值而非数组,可添加类型判断并包装为数组(需确保KrakenD模板环境支持reflect和slice函数):
{{if .promotionData}} "promotionData": { "identifier": "{{.promotionData.identifier}}", "description": "{{.promotionData.description}}" {{- /* 处理promotionBundleId:单个值转数组 */}} {{- $bundleIds := .promotionData.promotionBundleId}} {{- if not (reflect.IsSlice $bundleIds)}} {{- $bundleIds := slice $bundleIds}} {{- end}} {{- if gt (len $bundleIds) 0}} ,"promotionBundleId": [ {{- range $index, $id := $bundleIds -}} {{- if $index}},{{end}}"{{ $id }}"{{- end -}} ] {{- end}} {{- /* 处理promotionServiceId:单个值转数组 */}} {{- $serviceIds := .promotionData.promotionServiceId}} {{- if not (reflect.IsSlice $serviceIds)}} {{- $serviceIds := slice $serviceIds}} {{- end}} {{- if gt (len $serviceIds) 0}} ,"promotionServiceId": [ {{- range $index, $ele := $serviceIds -}} {{- if $index}},{{end}}"{{ $ele }}"{{- end -}} ] {{- end}} } {{else}} "promotionData": [] {{end}}
内容的提问来源于stack exchange,提问作者swaroop c
相关产品推荐
相关产品推荐

