我正在使用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
... ^
我做了什么明显错误的事吗? 谢谢你的帮助。
答案 0 :(得分:1)
子字符串的结束索引不包括在内。因此,您需要:
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('}')]
可能会更好: - )
答案 1 :(得分:0)
我最终得到了这个(谢谢@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}
EDIT。现在正在运作:
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), null值和field9,它应该是["something.2334", "something.9973"]
我想知道如何确保Json的格式正确(例如,稍后摄入Db)。
非常感谢