I'm parsing a chunk of text using the spring SpelExpressionParser TemplateParserContext to replace parts of the string. I'm setting a map as the root object of the context.
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 result;
This seems to work but requires me to reference each property using an expression that seems like overkill:
#{['my.key']}
Is there a way to simplify what I'm trying to do so that it more resembles spring's property file type syntax, e.g.
${my.key}
CodePudding user response:
Per @ArtemBilans comment , a MapAccessor in the parser context makes this work, with a slight adjustment. You need to reference everthing using the same syntax. By default the Parser uses #{} but you can change it to ${} if necessary.
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);