spel 多层list嵌套表达式踩坑记

news2025/6/6 10:05:49

场景

Expression exp = spelParser.parseExpression("#{#avgTable?.get(2)?.get(0)}", new TemplateParserContext());
String _result = exp.getValue(evalContext, String.class);

当avgTable?.get(2)为空时,Method threw 'java.lang.IndexOutOfBoundsException' exception.

在 Spring Expression Language (SpEL) 中,安全导航操作符 (?.) 通常可以防止 NullPointerException,但如果它不起作用,可能是以下原因导致的:


1. ?. 无法防止 IndexOutOfBoundsException

问题原因:

  • avgTable?.get(2) 如果 avgTableListsize() <= 2,会抛出 IndexOutOfBoundsException,而不是返回 null
  • ?. 只能防止 NullPointerException(即 avgTablenull 的情况),但无法阻止越界访问。

解决方案:

  • 改用 size() 检查:
    "#{(#avgTable != null && #avgTable.size() > 2) ? #avgTable.get(2)?.get(0) : null}"
    
  • 或使用 SafeList 包装(自定义方法,返回 null 而不是抛异常)。

2. SpEL 版本或解析方式问题

问题原因:

  • 某些旧版本的 SpEL 可能对 ?. 支持不完全。
  • 如果使用的是 TemplateParserContext(如 #{...}),确保语法正确。

解决方案:

  • 升级 Spring 版本(推荐 Spring 5+)。
  • 检查 SpEL 表达式是否正确解析:
    Expression exp = parser.parseExpression("#{#avgTable?.get(2)?.get(0)}", new TemplateParserContext());
    

3. avgTable 不是标准的 Java Bean/List/Map

问题原因:

  • 如果 avgTable 是自定义类,且 get(2) 不是标准方法(如数组访问或特殊数据结构),?. 可能不会按预期工作。
  • 例如,数组访问 arr[2] 越界会直接抛异常,?. 无法阻止。

解决方案:

  • 改用 ListMap 结构。
  • 或手动检查索引:
    "#{(#avgTable != null && #avgTable.length > 2) ? #avgTable[2]?.property : null}"
    

4. 嵌套对象访问方式错误

问题原因:

  • 如果 avgTable.get(2) 返回的对象没有 get(0) 方法,?. 也无法阻止 NoSuchMethodException
  • 例如:
    List<String> row = avgTable.get(2);  // 返回 String,但尝试调用 get(0)
    row?.get(0);  // String 没有 get(0) 方法,会抛异常
    

解决方案:

  • 确保对象结构正确:
    "#{#avgTable?.get(2) instanceof List ? #avgTable.get(2)?.get(0) : null}"
    

5. 表达式解析错误

问题原因:

  • 如果 SpEL 表达式语法错误(如括号不匹配),?. 可能不会生效。
  • 例如:
    "#{#avgTable?.get(2)?.get(0}"  // 缺少右括号
    

解决方案:

  • 检查表达式语法是否正确:
    "#{#avgTable?.get(2)?.get(0)}"  // 正确
    

推荐解决方案

1. 使用 size() 检查索引(适用于 List

Expression exp = parser.parseExpression(
    "#{(#avgTable != null && #avgTable.size() > 2) ? #avgTable.get(2)?.get(0) : null}",
    new TemplateParserContext()
);

2. 使用 Elvis 运算符提供默认值

Expression exp = parser.parseExpression(
    "#{#avgTable?.get(2)?.get(0) ?: 'DEFAULT'}",
    new TemplateParserContext()
);

3. 使用 try-catch(不推荐,仅备用)

Expression exp = parser.parseExpression(
    "#{T(org.springframework.util.ObjectUtils).nullSafeToString(#avgTable?.get(2)?.get(0))}",
    new TemplateParserContext()
);

总结

问题原因解决方案
IndexOutOfBoundsExceptionList.get(2) 越界检查 size()
NullPointerExceptionavgTablenull使用 ?.
自定义类无 get(0)对象结构错误检查类型
SpEL 语法错误表达式不合法修复语法
旧版 SpEL 问题版本兼容性升级 Spring

如果仍然有问题,建议打印 avgTable 的实际类型和结构:

System.out.println("avgTable class: " + avgTable.getClass());
System.out.println("avgTable size: " + (avgTable != null ? avgTable.size() : "null"));

这样可以更精准地定位问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2401530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度强化学习驱动的智能爬取策略优化:基于网页结构特征的状态表示方法

传统网络爬虫依赖静态规则&#xff08;如广度优先搜索&#xff09;或启发式策略&#xff0c;在面对动态网页&#xff08;如SPA单页应用&#xff09;、复杂层级结构&#xff08;如多层嵌套导航&#xff09;及反爬机制时&#xff0c;常表现出爬取效率低下、覆盖率不足等问题。本文…

如何轻松将视频从安卓设备传输到电脑?

现在&#xff0c;我们可以轻松地使用安卓手机拍摄高分辨率视频。然而&#xff0c;这些视频会占用大量的存储空间。如果您想将视频从安卓设备传输到电脑以释放存储空间、编辑素材或只是备份记忆&#xff0c;可以使用本文介绍的 8 种实用方法来完成视频传输。 第 1 部分&#xff…

时代星光推出战狼W60智能运载无人机,主要性能超市场同类产品一倍!

在刚刚结束的第九届世界无人机大会上&#xff0c;时代星光科技发布了其全新产品战狼W60智能运载无人机&#xff0c;并展示了基于战狼W60无人机平台的多种应用场景解决方案。据了解&#xff0c;该产品作为一款多旋翼无人机&#xff0c;主要性能参数均远超市场同类产品&#xff0…

BUUCTF[极客大挑战 2019]Secret File 1题解

[极客大挑战 2019]Secret File 1 分析&#xff1a;解题界面1&#xff1a;界面二&#xff1a;界面3&#xff1a; 总结: 分析&#xff1a; 事后来看&#xff0c;这道题主打一个走一步看一步。我们只能从题目的标题中猜到&#xff0c;这道题与文件有关。 解题 界面1&#xff1a…

Odoo电子邮件使用配置指南

在Odoo中配置邮件收发功能需要设置SMTP发件服务器和IMAP/POP3收件服务器&#xff0c;并确保DNS记录&#xff08;如SPF、DKIM&#xff09;正确&#xff0c;以避免邮件被标记为垃圾邮件。以下指南是详细配置步骤&#xff1a; 1. 配置出站邮件&#xff08;SMTP&#xff09; 1.1 使…

MacOS解决局域网“没有到达主机的路由 no route to host“

可能原因&#xff1a;MacOS 15新增了"本地网络"访问权限&#xff0c;在 APP 第一次尝试访问本地网络的时候会请求权限&#xff0c;可能顺手选择了关闭。 解决办法&#xff1a;给想要访问本地网络的 APP &#xff08;例如 terminal、Navicat、Ftp&#xff09;添加访问…

找到每一个单词+模拟的思路和算法

如大家所知&#xff0c;我们可以对给定的字符串 sentence 进行一次遍历&#xff0c;找出其中的每一个单词&#xff0c;并根据题目的要求进行操作。 在寻找单词时&#xff0c;我们可以使用语言自带的 split() 函数&#xff0c;将空格作为分割字符&#xff0c;得到所有的单词。为…

2025东南亚跨境选择:Lazada VS. Shopee深度对比

东南亚电商市场持续爆发&#xff0c;2025年预计规模突破2000亿美元。对跨境卖家而言&#xff0c;Lazada与Shopee仍是两大核心战场&#xff0c;但平台生态与竞争格局已悄然变化。深入对比&#xff0c;方能制胜未来。 一、平台基因与核心优势对比 维度 Lazada (阿里系) Shopee …

Java-39 深入浅出 Spring - AOP切面增强 核心概念 通知类型 XML+注解方式 附代码

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…

.NET 8集成阿里云短信服务完全指南【短信接口】

文章目录 前言一、准备工作1.1 阿里云账号准备1.2 .NET 8项目创建 二、集成阿里云短信SDK2.1 安装NuGet包2.2 配置阿里云短信参数2.3 创建配置类 三、实现短信发送服务3.1 创建短信服务接口3.2 实现短信服务3.3 注册服务 四、创建控制器五、测试与优化5.1 单元测试5.2 性能优化…

实现仿中国婚博会微信小程序

主要功能&#xff1a; 1、完成底部标签导航设计、首页海报轮播效果设计和宫格导航设计&#xff0c;如图1所示 2、在首页里&#xff0c;单击全部分类宫格导航的时候&#xff0c;会进入到全部分类导航界面&#xff0c;把婚博会相关内容的导航集成到一个界面里&#xff0c;如图2…

星闪开发之Server-Client 指令交互控制红灯亮灭案例解析(SLE_LED详解)

系列文章目录 星闪开发之Server-Client 指令交互控制红灯亮灭的全流程解析&#xff08;SLE_LED详解&#xff09; 文章目录 系列文章目录前言一、项目地址二、客户端1.SLE_LED_Client\inc\SLE_LED_Client.h2.SLE_LED_Client\src\SLE_LED_Client.c头文件与依赖管理宏定义与全局变…

day25-计算机网络-3

1. DNS解析流程 windows host文件是否配置域名对应的ip查询本地DNS缓存是否有这个域名对应的ip询问本地DNS&#xff08;网卡配置的&#xff09;是否知晓域名对应的ip本地DNS访问根域名解析服务器&#xff0c;但是根DNS只有顶级域名的记录&#xff0c;根告诉我们.cn顶级域名的D…

RunnablePassthrough介绍和透传参数实战

导读&#xff1a;在构建复杂的LangChain应用时&#xff0c;你是否遇到过需要在处理链中既保留原始输入又动态扩展上下文的场景&#xff1f;RunnablePassthrough正是为解决这类数据流处理问题而设计的核心组件。 本文通过深入剖析RunnablePassthrough的工作机制和实际应用&#…

JavaSec-XSS

反射型XSS 简介 XSS(跨站脚本攻击)利用浏览器对服务器内容的信任&#xff0c;攻击者通过在网页中注入恶意脚本&#xff0c;使这些脚本在用户的浏览器上执行&#xff0c;从而实现攻击。常见的XSS攻击危害包括窃取用户会话信息、篡改网页内容、将用户重定向到恶意网站&#xff0c…

echarts在uniapp中使用安卓真机运行时无法显示的问题

文章目录 一、实现效果二、话不多说&#xff0c;上源码 前言&#xff1a;我们在uniapp中开发的时候&#xff0c;开发的时候很正常&#xff0c;echarts的图形在h5页面上也是很正常的&#xff0c;但是当我们打包成安卓app或者使用安卓真机运行的时候&#xff0c;图形根本就没有渲…

STM32----IAP远程升级

一、概述&#xff1a; IAP&#xff0c;全称是“In-Application Programming”&#xff0c;中文解释为“在程序中编程”。IAP是一种对通过微控制器的对外接口&#xff08;如USART&#xff0c;IIC&#xff0c;CAN&#xff0c;USB&#xff0c;以太网接口甚至是无线射频通道&#…

C++优选算法 904. 水果成篮

文章目录 1.题目描述2.算法思路 3.完整代码容器做法数组做法 1.题目描述 看到这种题目&#xff0c;总觉得自己在做阅读理解&#xff0c;晕了&#xff0c;题目要求我们在一个数组里分别找出两种数字&#xff0c;并统计这两种数字分别出现一共是多少。 2.算法思路 采用哈希表滑…

Python6.5打卡(day37)

DAY 37 早停策略和模型权重的保存 知识点回顾&#xff1a; 过拟合的判断&#xff1a;测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint&#xff0c;还包含训练状态 早停策略 作业&#xff1a;对信贷数据集训练后保存权重&#xf…