NiFi 1.16.3中ExecuteGroovyScript脚本触发NumberFormatException求助
解决NiFi ExecuteGroovyScript的NumberFormatException问题
问题场景
在NiFi 1.16.3中使用ExecuteGroovyScript处理器,将固定长度格式的文本FlowFile转换为JSON时,执行过程中持续抛出NumberFormatException错误。
样本输入文本
+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
报错信息
All NodesExecuteGroovyScript[id=afb7a99f-0188-1000-0000-00004af5fb62] java.lang.NumberFormatException: java.lang.NumberFormatException
问题排查
原脚本的核心问题在于字段截取范围错误和数字转换未做安全校验:
- 固定长度字段的索引截取与实际文本不匹配,导致截取到的字符串包含非数字字符(比如字母、空格),调用
toBigDecimal()时抛出格式异常。 - 未处理空字符串或无效数字的情况,即使截取范围正确,若字段为空或包含非数字内容,直接转换也会报错。
修正后的Groovy脚本
import groovy.json.JsonBuilder import java.nio.charset.StandardCharsets import java.time.LocalDate import java.time.format.DateTimeParseException def flowFile = session.get() if (flowFile) { def datePattern = java.time.format.DateTimeFormatter.ofPattern('yyyy-MM-dd') def records = [] flowFile.read().withReader('ISO-8859-1') { reader -> reader.eachLine { line -> // 安全转换为BigDecimal的工具方法 def safeToBigDecimal = { str -> def trimmed = str?.trim() trimmed && trimmed.matches(/[+-]?\d+/) ? new BigDecimal(trimmed) : null } // 安全解析日期的工具方法 def safeParseDate = { str -> def trimmed = str?.trim() if (!trimmed || trimmed == '0000-00-00') return null try { LocalDate.parse(trimmed, datePattern) } catch (DateTimeParseException e) { null } } def record = [ SEQ_LD: 'ADMIN.SEQ_INFO.NEXTVAL', NO: safeToBigDecimal(line[0..10]), PA: line[11..12]?.trim() ?: '', PAR: safeToBigDecimal(line[13..23]), CD: line[24..27]?.trim() ?: '', CFOUR: line[28..31]?.trim() ?: '', DTIR: safeParseDate(line[32..41]), DEV: line[42..44]?.trim() ?: '', EXBL: safeToBigDecimal(line[45..60]), NEXBL: safeToBigDecimal(line[61..76]), SUSP: safeToBigDecimal(line[77..92]), NEXBL_SUSP: safeToBigDecimal(line[93..108]), SOLC: safeToBigDecimal(line[109..124]), MXBL: safeToBigDecimal(line[125..140]), MMIX: safeToBigDecimal(line[141..156]), ABD: safeToBigDecimal(line[157..172]), EXBLFF: safeToBigDecimal(line[173..188]), MTGR: safeToBigDecimal(line[189..204]), MKLM: safeToBigDecimal(line[205..220]), MXYR: safeToBigDecimal(line[221..236]), MHHH: safeToBigDecimal(line[237..252]), MOPO: safeToBigDecimal(line[253..268]), MNBFR: safeToBigDecimal(line[269..284]), CGTRH: line[285..289]?.trim() ?: '', IPOING: line[290..290]?.trim() ?: '', BGFTU: safeToBigDecimal(line[291..306]), DLJHJ: safeParseDate(line[307..316]), NHJGY: safeToBigDecimal(line[317..327]), 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) }
关键修改说明
- 添加安全转换工具方法:
safeToBigDecimal:先校验字符串是否为有效数字格式,只有符合规则才转换,否则返回null,彻底避免NumberFormatException。safeParseDate:添加try-catch捕获日期解析异常,同时处理空字符串和无效日期(如0000-00-00),返回null而非抛出错误。
- 字段截取验证:需根据实际文本的固定长度确认每个字段的索引范围,若样本文本的字段长度与原脚本假设不符,需重新调整
line[start..end]的索引值,确保截取到的是纯数字内容。
内容的提问来源于stack exchange,提问作者Jemna81
相关产品推荐
相关产品推荐

