修复 Groovy 中的 Json 格式问题:Apache NiFi ExecuteScript

Fixing Json formatting issue in Groovy: Apache NiFi ExecuteScript

我正在使用 Apache Nifi,我的一个流文件格式有点不正确 Json:

{
"field" : "value",
"field1" : "value1"

}0;0

我不想使用之前应用的转换,而是想使用 Groovy 脚本作为 ExecuteScript 的一部分。这是我目前拥有的:

import org.apache.nifi.processor.io.StreamCallback
import java.nio.charset.StandardCharsets
import org.apache.commons.io.IOUtils
import java.nio.charset.*


def flowFile = session.get()
if (!flowFile) return

def slurper = new groovy.json.JsonSlurper()

flowFile = session.write(flowFile, { inputStream, outputStream ->
    def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
    def resultingText = text.substring(0, text.indexOf('}'))
    def json = slurper.parseText(resultingText)

    outputStream.write(json.toString().getBytes(StandardCharsets.UTF_8))

} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)

但是,返回时出现以下错误:

ExecuteScript[id=69ae1948-f20b-446c-b33f-298c6faa7c98] Failed to process session due to org.apache.nifi.processor.exception.ProcessException: javax.script.ScriptException: javax.script.ScriptException: groovy.json.JsonException: expecting '}' or ',' but got current char [SPACE] with an int value of 32

The current character read is [SPACE] with an int value of 32
expecting '}' or ',' but got current char [SPACE] with an int value of 32
line number 5
index number 61

...^: org.apache.nifi.processor.exception.ProcessException: javax.script.ScriptException: javax.script.ScriptException: groovy.json.JsonException: expecting '}' or ',' but got current char [SPACE] with an int value of 32

The current character read is [SPACE] with an int value of 32
expecting '}' or ',' but got current char [SPACE] with an int value of 32
line number 5
index number 61

...^

我做错了什么吗? 感谢您的帮助。

子字符串的结束索引不包含在内。因此,您需要:

def resultingText = text.substring(0, text.indexOf('}') + 1)

或者,您可以使用 groovy 中的范围(含)

def resultingText = text[0..text.indexOf('}')]

那就是你的结果。使用 JsonSlurper 将其解析为地图毫无意义(除非您只想验证它是否有效)...并且 json.toString() 不会返回您想要的内容,它将返回一个字符串地图的表示

如果您的任何输入 json 有嵌套对象,这将中断 :-(

def resultingText = text[0..text.lastIndexOf('}')]

可能会更好:-)

我已经结束了(谢谢@tim_yates):

import org.apache.commons.io.IOUtils
import org.apache.nifi.processor.io.StreamCallback

import java.nio.charset.StandardCharsets

def flowFile = session.get()
if (!flowFile) return

def slurper = new groovy.json.JsonSlurper()

flowFile = session.write(flowFile, { inputStream, outputStream ->
    def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
    def resultingText = text[0..text.lastIndexOf('}')]
    def json = slurper.parseText(resultingText)

   outputStream.write(json.toString().getBytes(StandardCharsets.UTF_8))

} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)

贴出的例子只是真实例子的一部分Json。不幸的是, Json 有很多怪癖,例如用双引号表示值。例如:

{
 "field" : ""value""
}0;0

以上代码适用于以下格式:

{
 "field" : "value"
}0;0

我想我需要格式化 Json 然后我才能删除多余的字符。有没有一种简单的方法可以确保格式正确?

非常感谢

编辑:

其实我错了,运行脚本后的返回值是:

{field=value}

编辑。现在可以使用了:

import org.apache.commons.io.IOUtils
import org.apache.nifi.processor.io.StreamCallback

import java.nio.charset.StandardCharsets

def flowFile = session.get()
if (!flowFile) return

flowFile = session.write(flowFile, { inputStream, outputStream ->
    def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
    def resultingText = text[0..text.lastIndexOf('}')].replaceAll('""', '"')

    outputStream.write(resultingText.toString().getBytes(StandardCharsets.UTF_8))

} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)

但是,数据中仍然存在一些怪癖,这将成为以后数据流中的负担。这是完整的示例 Json:

{"field1": "D",
 "field2": "12345",
 "field3": "myText",
 "field4": ,
 "field5": "B2",
 "field6": "B",
 "field7": 74664",
 "field8": 2,
 "field9": [something."2334", something."9973"],
 "field10": ,
 "field11": "9,
 "field12": "J"}

我已经设法删除了双“”,但我关心的是右边或左边的值(例如 field7 和 field11),没有任何“”的值(例如 field8) ,空值和 field9,实际上应该是 ["something.2334", "something.9973"]

我想知道如何确保 Json 的格式正确(例如,以便稍后引入 Db)。

非常感谢