SpEL拆分属性为数组失败:ParseException异常排查求助
SpEL使用split('|')抛出ParseException的问题排查与解决
问题背景
使用SpEL表达式将配置文件中以|分隔的wisdoms属性拆分为数组时,抛出org.springframework.expression.ParseException,提示存在非终止字符串字面量。相关代码与配置如下:
代码示例
@Component @Qualifier("propertySourceBased") public class PropertySourceWisdomProvider implements WisdomProvider { @Value("#{'${wisdoms}'.split('|')}") private String[] wisdoms; }
配置文件内容
wisdoms = Tomorrow is often the busiest day of the week|\ I have always wanted to be somebody, but I see now I should have been more specific|\ Knowledge is like underwear. It is useful to have it, but not necessary to show it off|\ Go to Heaven for the climate, Hell for the company|\ Going to church doesn't make you a Christian any more than going to a garage makes you an automobile
异常信息
Caused by: org.springframework.expression.ParseException: Expression [#{'Tomorrow is often the busiest day of the week|I have always wanted to be somebody, but I see now I should have been more specific|Knowledge is like underwear. It is useful to have it, but not necessary to show it off|Go to Heaven for the climate, Hell for the company|Going to church doesn't make you a Christian any more than going to a garage makes you an automobile'.split('|')}] @381: Found non terminating string literal starting at position 381
问题原因
- 单引号冲突:配置字符串中包含
doesn't,其中的单引号'会与SpEL表达式外层包裹字符串的单引号冲突。SpEL解析时会误将这个单引号识别为字符串字面量的结束标记,导致后续内容无法被正确解析,抛出“非终止字符串字面量”异常。 - 正则特殊字符未转义:
split方法接收的参数是正则表达式,|是正则中的特殊元字符(表示逻辑或),直接使用会导致按空字符拆分,无法达到按|分隔字符串的预期效果。
解决方法
方案一:转义配置文件中的单引号
在配置文件中,用两个连续单引号''表示一个字面量单引号,修改配置行:
wisdoms = Tomorrow is often the busiest day of the week|\ I have always wanted to be somebody, but I see now I should have been more specific|\ Knowledge is like underwear. It is useful to have it, but not necessary to show it off|\ Go to Heaven for the climate, Hell for the company|\ Going to church doesn''t make you a Christian any more than going to a garage makes you an automobile
同时修改SpEL表达式,转义|为正则字面量:
@Component @Qualifier("propertySourceBased") public class PropertySourceWisdomProvider implements WisdomProvider { @Value("#{'${wisdoms}'.split('\\\\|')}") private String[] wisdoms; }
注:Java字符串中需要用
\\\\表示正则所需的\,最终SpEL解析后会得到split('\|'),实现按字面量|拆分。
方案二:改用双引号包裹SpEL中的字符串
在SpEL表达式中改用双引号包裹${wisdoms}替换后的字符串,避免与配置中的单引号冲突,同时转义|:
@Component @Qualifier("propertySourceBased") public class PropertySourceWisdomProvider implements WisdomProvider { @Value("#{\"${wisdoms}\".split('\\\\|')}") private String[] wisdoms; }
注:Java注解字符串中需要用
\"表示双引号,确保SpEL能正确识别字符串边界。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

