SpringBoot 引入 SPEL 模板字符串替换的两种方式
Spring 表达式语言 (SpEL)
官方文档:https://docs.spring.io/spring-framework/docs/6.0.x/reference/html/core.html#expressions
模板占位符 替换 {$name}
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.PropertyPlaceholderHelper;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
/**
* 内容占位符 替换
* <p>
* 模板占位符格式{$name}
*/
public class ContentHolderUtil {
/**
* 占位符前缀
*/
private static final String PLACE_HOLDER_PREFIX = "{$";
/**
* 占位符后缀
*/
private static final String PLACE_HOLDER_SUFFIX = "}";
private static final StandardEvaluationContext EVALUATION_CONTEXT;
private static final PropertyPlaceholderHelper PROPERTY_PLACEHOLDER_HELPER = new PropertyPlaceholderHelper(
PLACE_HOLDER_PREFIX, PLACE_HOLDER_SUFFIX);
static {
EVALUATION_CONTEXT = new StandardEvaluationContext();
EVALUATION_CONTEXT.addPropertyAccessor(new MapAccessor());
}
public static String replacePlaceHolder(final String template, final Map<String, String> paramMap) {
String replacedPushContent = PROPERTY_PLACEHOLDER_HELPER.replacePlaceholders(template,
new CustomPlaceholderResolver(template, paramMap));
return replacedPushContent;
}
private static class CustomPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
private final String template;
private final Map<String, String> paramMap;
public CustomPlaceholderResolver(String template, Map<String, String> paramMap) {
super();
this.template = template;
this.paramMap = paramMap;
}
@Override
public String resolvePlaceholder(String placeholderName) {
String value = paramMap.get(placeholderName);
if (null == value) {
String errorStr = MessageFormat.format("template:{0} require param:{1},but not exist! paramMap:{2}",
template, placeholderName, paramMap.toString());
throw new IllegalArgumentException(errorStr);
}
return value;
}
}
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("name","张三");
map.put("age","12");
// 注意:{$}内不能有空格
final String s = replacePlaceHolder("我叫 {$name}, 我今年 {$age} 岁了。", map);
System.out.println(s);
}
}
common-text 方式:模板字符转替换 ${}
-
添加依赖
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.10.0</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
-
测试
import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringSubstitutor; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Slf4j public class CommonTextUtil { // 占位符前缀 private static final String prefix = "${"; // 占位符后缀 private static final String suffix = "}"; /* * commons-text * */ public static String replaceVar(Map<String, Object> vars, String template) { if (!StringUtils.hasLength(template)) { log.info(String.format("调用%s方法失败,模板字符串替换失败,模板字符串不能为空", Thread.currentThread().getStackTrace()[1].getMethodName())); return null; } if (CollectionUtils.isEmpty(vars)) { log.info(String.format("调用%s方法失败,模板字符串替换失败,map不能为空", Thread.currentThread().getStackTrace()[1].getMethodName())); return null; } List<String> tempStrs = vars.keySet().stream().map(s -> prefix + s + suffix). collect(Collectors.toList()); tempStrs.forEach(t -> { if (!template.contains(t)) { throw new RuntimeException(String.format("调用%s方法失败,模板字符串替换失败,map的key必须存在于模板字符串中", Thread.currentThread().getStackTrace()[1].getMethodName())); } }); StringSubstitutor stringSubstitutor = new StringSubstitutor(vars); return stringSubstitutor.replace(template); } public static void main(String[] args) { /* * 错误的场景:比如${变量},{}内不能含有空格等等 * System.out.println(replaceVar(vals, "我叫${ name},今年${age }岁.")); * System.out.println(replaceVar(new HashMap<>(), temp)); * System.out.println(replaceVar(vals, "我叫张三")); * System.out.println(replaceVar(vals, "我叫${name},今年${age1}岁.")); * */ Map<String, Object> vals = new HashMap<>(); vals.put("name", "张三"); vals.put("age", "20"); String temp = "我叫${name},今年${age}岁."; System.out.println(replaceVar(vals, temp)); } }