SpringBoot application.yaml写SQL字符串字面量及EL1043E报错解决
问题现象
在SpringBoot项目的application.yaml配置文件中编写读取Kudu表数据的SQL查询,语句中使用字符串字面量时,程序运行抛出解析错误:
EL1043E: Unexpected token. Expected 'rcurly(})' but was 'identifier'
触发错误的配置片段如下,其中"FINNACE"为SQL中的字符串字面量:
filequery.map : '{ "filequery" : "SELECT FILE, project FROM ( SELECT FILE AS file_or_table_group, "FINNACE" AS project FROM finnance_data ) AS finnancedata" }'
故障原因
- 配置值外层用单引号包裹、整体带
{}结构,Spring加载配置时默认会触发SpEL表达式解析,解析过程中会把内部的双引号识别为字符串分隔符,FINNACE没有被正确识别为字符串内容,被判定为非法标识符,就会抛出缺少右大括号的错误。 - 现有配置里的SQL直接无规则断行,单引号包裹的YAML字符串会保留这些换行,传到数据库执行时也可能触发额外的SQL语法问题。
修复方案
三种方案选其一即可,优先推荐第一种,可维护性最高:
- 方案1:使用YAML块标量语法写配置,SQL内的字符串字面量改用单引号包裹
绝大多数SQL引擎(包括Kudu)都支持单引号作为字符串字面量的边界,不会和配置语法冲突,用|标识多行块标量也不用额外处理JSON的转义,改后配置如下:filequery: map: | { "filequery": "SELECT FILE, project FROM (SELECT FILE AS file_or_table_group, 'FINNACE' AS project FROM finnance_data) AS finnancedata" } - 方案2:关闭对应配置项的SpEL解析
如果是用@Value注解读取该配置,在注解参数中指定关闭SpEL解析即可,不会再把配置内容当成表达式处理;如果是用@ConfigurationProperties做属性绑定,默认不会解析SpEL,直接替换写法即可避开这个问题。@Value关闭SpEL的示例代码:@Value(value = "${filequery.map}", parseSpel = false) private Map<String, String> fileQueryMap; - 方案3:转义所有内部双引号
如果要保留原有行内JSON的写法,需要把JSON值内部、SQL内部的所有双引号都做转义处理:
注意:这种写法后续修改SQL时很容易漏写转义符再次触发错误,不推荐长期使用。filequery.map: '{"filequery": "SELECT FILE, project FROM (SELECT FILE AS file_or_table_group, \"FINNACE\" AS project FROM finnance_data) AS finnancedata"}'
内容的提问来源于stack exchange,提问作者Tinku
相关产品推荐
相关产品推荐

