NiFi 1.16.3类的Groovy Scrtipt错误属性DateTimeFormatter

xj3cbfub  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(101)

我生成了一个数据格式为(文本)的流文件:

+0002150736YY+0701748361MN      0001-01-01SSD+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000-000000000002860+000000000000000+000000000000000     1+0000000000000002023-05-23+0701748361                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
+0002152097XX+0701763467RR      0001-01-01SSF+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000011845+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000+000000000000000     1+0000000000000002023-05-23+0701763467

我尝试使用ExecuteGroovyScript进程执行一个groovy脚本,以输出一个json文件,并且每个键都有其值:

import groovy.json.JsonBuilder
import java.nio.charset.StandardCharsets
import java.time.LocalDate

def flowFile = session.get()
if (flowFile) {
    def datePattern = DateTimeFormatter.ofPattern('yyyy-MM-dd')

    def records = []

    flowFile.read().withReader('ISO-8859-1') { reader ->
        reader.eachLine { line ->
            def record = [
                SEQ_LD: 'ADMIN.SEQ_INFO.NEXTVAL',
                NO: line[0..10]?.trim()?.toBigDecimal(),
                PA: line[11..12]?.trim() ?: '',
                PAR: line[13..23]?.trim()?.toBigDecimal(),
                CD: line[24..27]?.trim() ?: '',
                CFOUR: line[28..31]?.trim() ?: '',
                DTIR: line[32..41]?.trim() != '0000-00-00' ? LocalDate.parse(line[32..41]?.trim(), datePattern) : null,
                DEV: line[42..44]?.trim() ?: '',
                EXBL: line[45..60]?.trim()?.toBigDecimal(),
                NEXBL: line[61..76]?.trim()?.toBigDecimal(),
                SUSP: line[77..92]?.trim()?.toBigDecimal(),
                NEXBL_SUSP: line[93..108]?.trim()?.toBigDecimal(),
                SOLC: line[109..124]?.trim()?.toBigDecimal(),
                MXBL: line[125..140]?.trim()?.toBigDecimal(),
                MMIX: line[141..156]?.trim()?.toBigDecimal(),
                ABD: line[157..172]?.trim()?.toBigDecimal(),
                EXBLFF: line[173..188]?.trim()?.toBigDecimal(),
                MTGR: line[189..204]?.trim()?.toBigDecimal(),
                MKLM: line[205..220]?.trim()?.toBigDecimal(),
                MXYR: line[221..236]?.trim()?.toBigDecimal(),
                MHHH: line[237..252]?.trim()?.toBigDecimal(),
                MOPO: line[253..268]?.trim()?.toBigDecimal(),
                MNBFR: line[269..284]?.trim()?.toBigDecimal(),
                CGTRH: line[285..289]?.trim() ?: '',
                IPOING: line[290..290]?.trim() ?: '',
                BGFTU: line[291..306]?.trim()?.toBigDecimal(),
                DLJHJ: line[307..316]?.trim() != '0000-00-00' ? LocalDate.parse(line[307..316]?.trim(), datePattern) : null,
                NHJGY: line[317..327]?.trim()?.toBigDecimal(),
                AACBT: line[328..328]?.trim() ?: '',
                TRT: LocalDate.parse('2023-06-05', datePattern)
            ]
            records << record
        }
    }

    def json = new JsonBuilder(records)
    def jsonBytes = json.toString().getBytes(StandardCharsets.UTF_8)
    flowFile = session.write(flowFile, { outputStream ->
        outputStream.write(jsonBytes)
    } as OutputStreamCallback)

    flowFile = session.putAttribute(flowFile, 'filename', 'output.json')
    session.transfer(flowFile, REL_SUCCESS)
}

但每次我得到这个错误,我不明白问题在哪里:

All NodesExecuteGroovyScript[id=afb7a99f-0188-1000-0000-00004af5fb62] java.lang.NumberFormatException: java.lang.NumberFormatException

有什么需要帮忙的吗?谢谢你

wd2eg0qa

wd2eg0qa1#

NumberFormatException表示您试图转换为BigDecimal的某些字段不是数字。很可能其中一个字段为空,这将触发NumberFormatException。但是,你的情况比这更糟,因为每条线都可能有其他线没有的问题。问题可能在第5434行,但您不知道是哪一行有问题,因为NFE不会将该行从数据中取出。所以,你需要更好的调试。现在就像大海捞针。
我的建议是构建一个小方法来执行该逻辑,而不是一遍又一遍地内联它。将内联line[0..10]?.trim()?.toBigDecimal()转换为:

Number toNumber( String line, ObjectRange range) {
   try {
      String v = line[range]?.trim()
      return v ? v.toBigDecimal() : null   // this will handle v == null or v is empty
   } catch( Exception ex ) {
      throw new Exception("Encountered exception at ${range} in line ${line}: ${ex}", ex)
   }
}

然后更改:

def record = [
                SEQ_LD: 'ADMIN.SEQ_INFO.NEXTVAL',
                NO: toNumber(line, 0..10 ),
                PA: line[11..12]?.trim() ?: '',
                PAR: toNumber(line, 13..23 ),
                CD: line[24..27]?.trim() ?: '',
                ...
]

如果你仍然有问题,你可以做一些事情来确定哪个字段有问题,通过捕获异常(即NFE),并在消息中的范围内抛出一个新的异常来知道哪个部分有问题。
然后,在解析时需要跟踪行号,以便在发现问题时显示出来。您需要在循环中捕获异常,并写出出错行的行号。可能最好通过抛出一个带有行号的异常来停止整个过程:

int lineNumber = 1
reader.eachLine { line ->
   try {
      ....your logic here....
      lineNumber++
   } catch( Exception ex ) {
      throw new IOException( "Exception encountered at line ${lineNumber}: ${ex.getMessage()}", ex )
   }
}

相关问题