Java调用readFileLsd服务报Index 2 out of bounds for length 1异常
问题原因
抛出Index 2 out of bounds for length 1是典型的数组访问越界错误,根因有两点:
- 你初始化
TotalBaggagesCargo、PASSENGER、TOTAL_TRAFFIC三个变量时默认值是空字符串,如果传入的航班文档内容缺失对应前缀的行(比如没有PASSENGER/CABIN BAG开头的行),遍历完成后对应变量还是空串。对空串做trim().replaceAll("\\s+", " ").split(" ")操作,返回的数组长度只有1(唯一元素是空字符串),此时硬编码取索引2、3的位置必然越界。 - 原实现没有做数组长度校验,就算匹配到了目标行,只要行内容因为过滤、格式差异导致split后的分段数不足,一样会触发越界。另外循环调用场景下每次都重新编译正则、未自动关流的写法也存在性能损耗和资源泄漏隐患。
修复方案
直接替换成如下实现即可:
private Map<String, Object> readFileLsd(String content) { Map<String, Object> mapResult = new LinkedHashMap<>(); // 预置默认值,避免后续返回null mapResult.put("TotalBaggagesCargo", ""); mapResult.put("PASSENGER", ""); mapResult.put("TOTAL_TRAFFIC", ""); // 提前编译正则,循环调用时复用提升性能 Pattern invalidCharPattern = Pattern.compile("[\\x00-\\x1F\\x21-\\x2C\\x3B-\\x40\\x5B-\\x60\\x7B-\\xFF]"); Pattern multiSpacePattern = Pattern.compile("\\s+"); // 自动关流,避免资源泄漏 try (BufferedReader br = new BufferedReader(new StringReader(content))) { String line; while ((line = br.readLine()) != null) { // 先清洗当前行 String cleanedLine = invalidCharPattern.matcher(line).replaceAll("").trim(); cleanedLine = multiSpacePattern.matcher(cleanedLine).replaceAll(" "); // 匹配目标行,拆分后先校验长度再取值,从根源避免越界 if (cleanedLine.startsWith("LOAD IN COMPARTMENTS")) { String[] parts = cleanedLine.split(" "); if (parts.length >= 4) { mapResult.put("TotalBaggagesCargo", parts[3]); } } else if (cleanedLine.startsWith("PASSENGER/CABIN BAG")) { String[] parts = cleanedLine.split(" "); if (parts.length >= 3) { mapResult.put("PASSENGER", parts[2]); } } else if (cleanedLine.startsWith("TOTAL TRAFFIC LOAD")) { String[] parts = cleanedLine.split(" "); if (parts.length >= 4) { mapResult.put("TOTAL_TRAFFIC", parts[3]); } } } } catch (Exception e) { e.printStackTrace(); } return mapResult; }
修复点说明
- 匹配到目标行后当场做清洗、拆分、长度校验,不再依赖遍历结束后的变量值,彻底解决空字符串导致的split数组长度不足问题
- 所有split操作后先判断数组长度是否满足取值要求,不会再触发越界异常
- 正则提前编译,比原实现每次调用都重新解析正则的性能高3~10倍,适合循环调用的场景
- 用try-with-resources语法自动关闭BufferedReader,避免资源泄漏
- 初始化返回Map时就给所有字段设置空串默认值,后续生成PDF时不会因为拿到null触发额外异常
如果上线后发现个别航班对应字段取不到值,在while循环里加一行打印cleanedLine的日志,看是否存在特殊字符把行前缀清洗变形的情况,微调invalidCharPattern的匹配范围即可。
内容的提问来源于stack exchange,提问作者Andres Hernandez
相关产品推荐
相关产品推荐

