Spring SpEL解析含特殊字符的逻辑表达式失败问题咨询
解决Spring SpEL解析含特殊字符字符串表达式的问题
你遇到的问题根源是:SpEL中字符串用单引号包裹,当字符串内部出现单引号时,解析器会误将其识别为字符串的结束标记,进而引发语法解析失败。比如你的示例里'Ha'il',中间的单引号会被当成第一个单引号的闭合符号,剩余的单引号就会导致语法错误。
以下是几种可行的解决方案:
方案1:转义字符串内部的单引号
SpEL规定,字符串内部的单引号需要用两个连续的单引号来转义,解析器会把这两个连续单引号识别为字符串的一部分。修改后的表达式如下:
'Ha''il'.equalsIgnoreCase('Dubai') || 'Ha''il'.equalsIgnoreCase('Bangkok') || 'Ha''il'.equalsIgnoreCase('Phuket') || 'Ha''il'.equalsIgnoreCase('Abha') || 'Ha''il'.equalsIgnoreCase('Ha''il')
方案2:使用SpEL文本块(Spring 5.2及以上版本支持)
如果你的Spring版本在5.2或更高,可以用三重双引号"""包裹字符串,内部的单引号无需转义,写法更简洁直观:
"""Ha'il""".equalsIgnoreCase('Dubai') || """Ha'il""".equalsIgnoreCase('Bangkok') || """Ha'il""".equalsIgnoreCase('Phuket') || """Ha'il""".equalsIgnoreCase('Abha') || """Ha'il""".equalsIgnoreCase("""Ha'il""")
这种方式适合包含大量特殊字符的字符串,不用频繁处理转义逻辑。
方案3:通过变量传入字符串(更安全灵活)
如果字符串是动态生成的,或者想避免在表达式里处理转义,可以把字符串作为变量传入SpEL上下文,表达式直接引用变量即可:
修改你的evaluate方法:
private final ExpressionParser parser = new SpelExpressionParser(); public boolean evaluate(String targetCity) { try { StandardEvaluationContext context = new StandardEvaluationContext(); context.setVariable("targetCity", targetCity); String expressionString = "#targetCity.equalsIgnoreCase('Dubai') || #targetCity.equalsIgnoreCase('Bangkok') || #targetCity.equalsIgnoreCase('Phuket') || #targetCity.equalsIgnoreCase('Abha') || #targetCity.equalsIgnoreCase('Ha''il')"; var expression = parser.parseExpression(expressionString); var result = expression.getValue(context, Boolean.class); return result; } catch (ParseException | SpelEvaluationException exception) { throw exception; } }
调用时直接传入"Ha'il"即可,无需转义,同时还能避免表达式注入风险,安全性更高。
内容的提问来源于stack exchange,提问作者Noshaf
相关产品推荐
相关产品推荐

