好用的消息模板占位符替换工具类

最近遇到一个需求,消息通知,要动态替换模板里占位符的参数,并且参数值还都不一样,例如:

【讯飞开放平台】尊敬的${name},您提交的星火认知大模型体验申请已通过审核,请在遵守相关协议的前提下进行体验。您可以通过电脑或手机访问官网(https://xinghuo.xfyun.cn/desk?phone=${phone}),选择“手机快捷登录”,使用本手机号完成验证后体验。再次感谢您的关心与支持!

介绍两种不同的模板参数替换方式

方式一

使用第三方依赖 commons-text ,不同版本地址:链接

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.10.0</version>
</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;

/**
 * 内容占位符 替换
 * <p>
 * 模板占位符格式
 */

@Slf4j
public class CommonTextUtil {

    /**
     * 前缀
     */

    private static final String PREFIX = "${";

    /**
     * 后缀
     */

    private static final String SUFFIX = "}";

    /**
     * 模板参数替换方法
     * @param map 替换的参数
     * @param template 模板
     * @return
     */

    public static String replaceVar(Map<String, Object> map, String template) {
        if (!StringUtils.hasLength(template)) {
            log.info(String.format("调用%s方法失败,模板字符串替换失败,模板字符串不能为空",
                    Thread.currentThread().getStackTrace()[1].getMethodName()));
            return null;
        }
        if (CollectionUtils.isEmpty(map)) {
            log.info(String.format("调用%s方法失败,模板字符串替换失败,map不能为空",
                    Thread.currentThread().getStackTrace()[1].getMethodName()));
            return null;
        }
        List<String> tempStrs = map.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(map);
        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, "我叫ceshi"));
         * System.out.println(replaceVar(vals, "我叫${name},今年${age1}岁."));
         * */

        Map<String, Object> map = new HashMap<>();
        map.put("name""小明");
        map.put("age""20");
        String temp = "我叫${name},今年${age}岁.";
        System.out.println(replaceVar(map, temp));
    }
}

输出结果:我叫小明,今年20岁.

具体支持哪些特殊符号可支持替换的前缀和后缀,可以看源码类 StringSubstitutor

方式二

使用 SpringPropertyPlaceholderHelper 替换模板中的参数,

使用方法,以下工具类可直接使用

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());
    }

    /**
     * 模板参数替换方法
     * @param template 模板
     * @param paramMap 参数
     * @return
     */

    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);
    }
}

结果:我叫 小明, 我今年 12 岁了。

原文始发于微信公众号(师小师):好用的消息模板占位符替换工具类

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/226353.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!