简介
占位符,顾名思义就是先占住一个位置,占位符解析就是把这事先占住的位置解析成,所想要的值。常见的占位符有#{},${},{}等等。使用占位符有好处是采用统一的表达方式,根据不同解析策略,可以有不同的结果;
占位符解析流程
- 确定所要解析占位符的前缀和后缀
- 取出前后缀所包裹的标记,token
- 对token进行解析及占位符的替换
具体解析过程
1、定义TokenParser
import com.weikun.handler.TokenHandler;
public class TokenParser {
private String prefix;//占位符前缀
private String suffix;//占位符后缀
private TokenHandler tokenHandler;//token解析策略
public TokenParser(String prefix, String suffix, TokenHandler tokenHandler) {
this.prefix = prefix;
this.suffix = suffix;
this.tokenHandler = tokenHandler;
}
//简单的解析,没有考虑到太多的业务场景
public String parse(String content) {
//1、context为null或者是空字符串,则根据自己的业务场景进行解析
if (content == null || content.isEmpty()) {
return "";
}
//采用笨办法解决多个占位符问题
while (true) {
StringBuilder builder = new StringBuilder();
//2、找到前缀在content中的位置,如果prefixIndex为-1,直接返回content
int prefixIndex = content.indexOf(prefix);
if (prefixIndex == -1) {
return content;
}
//3、找到后缀在content中的位置,suffixIndex-1,直接返回content
int suffixIndex = content.indexOf(suffix);
if (suffixIndex == -1) {
return content;
}
//prefixIndex > suffixIndex,直接返回content
if (prefixIndex > suffixIndex) {
return content;
}
//4、取出所要解析的token
String token = content.substring(prefixIndex + prefix.length(), suffixIndex);
//5、解析token
String resolveToken = tokenHandler.resolveToken(token);
//6、替换占位符
builder.append(content.substring(0, prefixIndex));
builder.append(resolveToken);
builder.append(content.substring(suffixIndex + suffix.length()));
content = builder.toString();
}
}
}
2、定义TokenHandler
public interface TokenHandler {
//解析传递过来的token
String resolveToken(String token);
}
举几个实现类例子
1)、MapTokenHandler
import java.util.HashMap;
import java.util.Map;
public class MapTokenHandler implements TokenHandler {
private Map<String, String> map = new HashMap<>();
public MapTokenHandler(Map<String, String> map) {
this.map = map;
}
@Override
public String resolveToken(String token) {
return map.get(token);
}
}
2)、ListTokenHandler
import java.util.List;
public class ListTokenHandler implements TokenHandler {
private List<String> list;
public ListTokenHandler(List<String> list) {
this.list = list;
}
@Override
public String resolveToken(String token) {
int index = Integer.parseInt(token);
return list.get(index);
}
}
3)、抽象类BeanTokenHandler根据具体业务场景指定泛型类型
public abstract class BeanTokenHandler<T> implements TokenHandler {
private T bean;
public BeanTokenHandler(T bean) {
this.bean = bean;
}
}
总结
占位符解析可以让模板代码具有很高的灵活性,根据不同的策略产生不同的结果,也可以借助Ognl或者是spring的SPEL对普通的Javabean进行解析,另外可以采用默认值的方式例如${name:zs},根据具体需求来吧。还有日志框架中的替换操作,直接把{},替换成对应的字符串,这个就相对简单些。