Как использовать ссылку на свойство ${ключ:по умолчанию} во время ручной оценки языка выражений Spring

#java #spring #spring-el

Вопрос:

Я анализирую фрагмент текста с помощью spring SpelExpressionParser TemplateParserContext для замены частей строки. Я устанавливаю карту в качестве корневого объекта контекста.

  String htmlText = IOUtils.toString(MailService.class.getResourceAsStream(resourceName),Charset.defaultCharset());


        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(htmlText, new TemplateParserContext());
        StandardEvaluationContext context = new StandardEvaluationContext();
        
        if(contextMap != null) {
            context.setRootObject(contextMap);
        }

        String result = expression.getValue(context,String.class);
 
        return resu<
 

Это, кажется, работает, но требует, чтобы я ссылался на каждое свойство, используя выражение, которое кажется излишним:

 #{['my.key']}
 

Есть ли способ упростить то, что я пытаюсь сделать, чтобы это больше напоминало синтаксис типа файла свойств spring, например

 ${my.key}
 

Комментарии:

1. Попробуйте добавить MapAccessor к этому StandardEvaluationContext .

2. Спасибо! Это сработало.

Ответ №1:

Согласно комментарию @ArtemBilans , MapAccessor в контексте синтаксического анализатора выполняет эту работу с небольшой корректировкой. Вам нужно ссылаться на что угодно, используя один и тот же синтаксис. По умолчанию синтаксический анализатор использует # {}, но при необходимости вы можете изменить его на $ {}.

 ExpressionParser parser = new SpelExpressionParser();
TemplateParserContext templateParserContext = new TemplateParserContext();
StandardEvaluationContext context = new StandardEvaluationContext();
//add map accessor to allow referencing map properties without ['']
context.addPropertyAccessor(new MapAccessor());

//bean has 'name' property
Bean bean = new Bean("myname");
//create a map with a bean, a string, and a nested map as props
Map<String,Object> map = MapUtils.createHashMap("w", "world","b",bean,"nested", MapUtils.createHashMap("key","others"));
//all values can be accessed using standard #{a.b.c} syntax
Expression expression = parser.parseExpression("hello #{w} from #{b.name} and #{nested.key}", templateParserContext);

//result is: 'hello world from myname and others'
String result = (String) expression.getValue(context, map);