使用包含单引号的字符串键进行 EL 映射查找

EL map lookup using string key containing single quote

我有一个 Java HashMap<String,String> 正在通过来自 Spring 的 ModelAndView 提供给 JSP 页面 (itemTypesByKey) ,以及一个包含键列表的单独结构。 (这些键可能会或可能不会导致有效查找。)我枚举这些键,并从地图中获取值。

Map<String, String> itemTypes = new HashMap<>();
itemTypes.put("NormalValue", "INGREDIENT");
itemTypes.put("Apostro'Value", "INGREDIENT");
ModelAndView mav = ...
mav.addObject("itemTypesByKey", itemTypes);

我看到的问题 是,如果我的密钥包含撇号,查找将失败。

我的代码(用于调试目的):

Key Name: ${currentKeyName}
Not Empty: ${not empty itemTypesByKey[currentKeyName]}
Type: ${itemTypesByKey[currentKeyName]}
All Suite Types: ${itemTypesByKey}

结束打印,两个单独的键:

Key Name: NormalValue
Not Empty: true
Type: INGREDIENT
All Suite Types: {NormalValue=INGREDIENT, Apostro'Value=INGREDIENT}

Key Name: Apostro'Value
Not Empty: false
Type:
All Suite Types: {NormalValue=INGREDIENT, Apostro'Value=INGREDIENT}

我理解转义撇号 文字 当它们用于查找值时,但是如果我的键 包含 一个,为什么这会失败撇号?无论我的键的值是否包含特殊字符,我如何才能安全地在我的地图中执行查找?

编辑: 我正在使用 Spring 版本 3.1.4(mvc、表达式等),这个问题不影响包含感叹号的键,或其他我想测试的特殊字符。

下面是一些测试和结果。为了在键中使用撇号,您必须使用两个单引号。最重要的是,其中包含单引号或特殊字符(感叹号、双引号等)的键需要用单引号括起来。底线是用单引号将您的键括起来,如果您的键中有单引号,请使用两个单引号。

public static void main(String[] args) {
    ExpressionParser parser = new SpelExpressionParser();
    Map<String,String> itemTypes = (Map) parser.parseExpression("{NormalValue:'INGREDIENT',ApostroValue:'INGREDIENT'}").getValue();
    for (Map.Entry<String, String> e : itemTypes.entrySet())
        System.out.println(e.getKey() + ": " + e.getValue());
}

可以很好地打印键和值

parseExpression("{NormalValue:'INGREDIENT',Apostro'Value:'INGREDIENT'}")

线程 "main" org.springframework.expression.spel.SpelParseException 中的异常:EL1046E:(pos 51):找不到字符串的终止符

parseExpression("{NormalValue:'INGREDIENT',Apostro''Value:'INGREDIENT'}")

线程 "main" org.springframework.expression.spel.SpelParseException 中出现异常:EL1043E:(位置 33):意外标记。预计 'colon(:)' 但 'literal_string'

parseExpression("{NormalValue:'INGREDIENT','Apostro''Value':'INGREDIENT'}")

打印效果很好

parseExpression("{NormalValue:'INGREDIENT',Apostro\"Value:'INGREDIENT'}")

线程 "main" org.springframework.expression.spel.SpelParseException 中的异常:EL1045E:(位置 33):找不到字符串的终止“”

parseExpression("{NormalValue:'INGREDIENT','Apostro\"Value':'INGREDIENT'}")

打印效果很好

parseExpression("{NormalValue:'INGREDIENT',Apostro!Value:'INGREDIENT'}")

线程 "main" org.springframework.expression.spel.SpelParseException 中出现异常:EL1043E:(位置 33):意外标记。预计 'colon(:)' 但 'not(!)'

parseExpression("{NormalValue:'INGREDIENT','Apostro!Value':'INGREDIENT'}")

打印效果很好