场景: 项目中常常会有一些message , 如邮件, 短信,  UI的提示信息, 多数情况,写在代码中,或者配置文件xxx.properties, @value 或者读取xxx.properties ,这两种方案都...

1.好处,统一管理

2.动态管理,如配置了appolo ,  配置中心

 3. 配置国际化, 如中文 ,英文

 

方式0 (spring 自带工具PropertyPlaceholderHelper, 可以换用 @{ 作为前缀,解决@value 不可解析的问题 )

import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.SystemPropertyUtils;
import java.util.Properties;
public class MsgUtil {
   public static void main(String[] args) {
        PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX, SystemPropertyUtils.PLACEHOLDER_SUFFIX);
       String offline_ivt_email_notify_template="${userName} ,您好!<br>你已经通过 <strong> 【${companyName}】.</strong><strong>  [${job}]  </strong> 职位的线上面试";
       Properties properties = new Properties() {{
           put("userName", "userName");
           put("companyName", "companyName");
           put("job", "job");
       }};
       String content= propertyPlaceholderHelper .replacePlaceholders(offline_ivt_email_notify_template, properties);
       System.err.println(content);
   }
}

 

 

 

方式1:(  消息模板占位符使用与详解

消息模板

在消息相关的系统开发过程中,我们通常会对用户提供消息模板的配置,如短信模板,通讯软件消息模板,邮件消息模板,站内信消息模板等,用户配置好模板后,可调用消息系统的api,传递消息参数,消息系统根据模板内容对占位符进行替换,发送消息。

  • 模板样例

尊敬的:${userName} 您好,您有${integralCount}积分未使用,现有${activityName}活动,大礼包为您准备好了!戳${activityUrl}参加吧!

freemarker

<dependency>
   <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

 

案例一:

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;

 

    @Test
    public void test() {
      try {
        String templateName ="ActivityMessage";
        Template template = new Template(templateName, getTemplate(), new Configuration(Configuration.VERSION_2_3_30));
//        Template template1 = new Template(templateName, getTemplate(), new Configuration(new Version("2.3.30")));
        StringWriter result = new StringWriter();
        template.process(getParams(),result);
        System.out.println(result.toString());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

  public Map<String, Object> getParams() {
    Map<String, Object> params =new HashMap<>(8);
    params.put("userName","Sea");
    params.put("integralCount",100.3456);
    params.put("activityName","新用户活动");
    params.put("activityUrl","jd.com");
    return params;
  }
  // 三目运算 ${ (type == SPOT’) ?string(‘热点词’,’热点搜索’)}
  public String getTemplate() {
//    return "尊敬的:${userName} 您好,您有${integralCount?string(\"#.##\")}积分未使用,现有${activityName}活动,大礼包为您准备好了!戳${activityUrl}参加吧!";
    //if userName==Sea print("my boss" ) 条件语句  <#if userName == \"Sea\">, my  boss  </#if>"
    return "尊敬的:${userName}  <#if userName == \"Sea\">, my  boss  </#if>" +
            " 您好,您有${integralCount}积分未使用,现有${activityName}活动,大礼包为您准备好了!戳${activityUrl}参加吧!";
  }

 案例二:

  @Test
  public void notifyMsgTemplate() throws Exception{
  // 替换 ${name?replace("\n","好好")}
  // 三目表达式 ${ (sex=='1')? string('先生','女士')}
  // 取得list的长度:${fields?size}
  // 字符串分割 ${(reservationTime?split(','))?size}
  // if 条件语句  <#if userName == \"Sea\">, my  boss  </#if>"
  // 遍历list  <#list (reservationTime?split(',')) as k>   ${k} ---- </#list>
    String messageTemplate="尊敬的: ${inviteeName} ${ (sex=='1')? string('先生','女士')}"+
            " 你已经通过 ${company} : ${job} 职位的初面," +
//            "诚挚的邀请你 在如下时间  ${reservationTime}  ${((reservationTime?split(','))?size>0)?string('之一','')}   到公司完成面试 , \n" +
            "诚挚的邀请你 在如下时间  ${reservationTime}  <#if ((reservationTime?split(','))?size>0) >  之一  </#if>  到公司完成面试 , \n" +
            "诚挚的邀请你 在如下时间  <#list (reservationTime?split(',')) as k>   ${k} ---- </#list>    <#if ((reservationTime?split(','))?size>0) >  之一  </#if>  到公司完成面试 , \n" +
            "诚挚的邀请你 在如下时间   ${reservationTime?replace(',',' 或者 ')}   <#if ((reservationTime?split(','))?size>0) >  之一  </#if>  到公司完成面试 , \n" +
            "请在[Sea-APP]上确认前往公司面试的时间,以便人事安排时间, 感谢!  智帮惠-职聘APP下载链接: https://www.sea.com/sea-app.apk";

    JSONObject params = new JSONObject() {{
      put("inviteeName", "lily");
      put("sex", "0");
      put("job", "高级技师");
      put("company", "Sea conpany");
      put("reservationTime", "4月6号 9:00,4月7号 9:00");
    }};

    Template template = new Template("xx", messageTemplate, new Configuration(Configuration.VERSION_2_3_30));
    StringWriter result = new StringWriter();
    template.process(params,result);
    System.out.println(result.toString());
  }

 

 

 

方式2: commons-text

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.10.0</version>
</dependency>

 

@Test
public void void() {
    StringSubstitutor strSubstitutor =new StringSubstitutor(getParams());
    String messageContent =strSubstitutor.replace(getTemplate());
    System.out.println(messageContent);
}
 
public Map<String, Object> getParams() {
    Map<String, Object> params =new HashMap<>(8);
    params.put("userName","fly");
    params.put("integralCount",100.3456);
    params.put("activityName","新用户活动");
    params.put("activityUrl","jd.com");
    return params;
}
 
public String getTemplate() {
    return "尊敬的:${userName} 您好,您有${integralCount}积分未使用,现有${activityName}活动,大礼包为您准备好了!戳${activityUrl}参加吧!";
}

 

 

模板类的展位符的场景下,通常使用相同名称参数替换的方式,我们可以采用freemarker或者commons-text,相对来讲commons-text使用起来代码更加简洁。

 

方式3:(更加适合国际化)

使用:

一.依赖:

     
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

 

二.配置文件xxx.properties位置:

 默认名字为 messages.properties

内容 :eg

     //event.validation.content= Notification \n{0} exception was detected, caused by :\n\n{1} \n\nSincerely \XXX Team
     //event.validation.subject=ERROR: Validation error found for booking <{0}>

 

  

三.配置类:

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;

import java.util.Locale;


@Component
@Slf4j
public class MesgHelper {

    private static MessageSource messageSource;

    public static MessageSource getMessageSource() {
        return messageSource;
    }
    @Autowired
    public void setMessageSource(MessageSource msgSource) {
        MesgHelper.messageSource = msgSource;
    }

    /**
     * Convert single message according to locale.
     *
     * @param mesgKey
     * @param values
     * @param locale
     * @return
     */
    public static String getMessage(String mesgKey,Object[] values,Locale locale)    {
        Locale locale1 = locale!=null?locale:Locale.US;
        String mesgText = null;

        if(mesgKey != null && locale1 != null)    {
            mesgText = messageSource.getMessage(mesgKey, values, locale1);
        }
        return mesgText;
    }
}

 

四.使用:

   //注入
      @Autowired
      MesgHelper mesgHelper

    private static Runnable validationNotify(String bookingNo,String mesgKeys,String body) {
        return ()->{
            log.debug("Current thread is {}",Thread.currentThread());
            log.info("@@!!@@ NOT pass the null validation checking , below data not allow null: {}", mesgKeys);
            LinkedHashMap msgBody = JSONObject.parseObject(body,new TypeReference<LinkedHashMap<String, Object>>(){}
                    ,Feature.OrderedField);
            String mailBody = JSONObject.toJSONString(msgBody,
                    SerializerFeature.PrettyFormat,
                    SerializerFeature.WriteMapNullValue);
        //参数变量 用{0}  {2} 表示
     //event.validation.content= Notification \n{0} exception was detected, caused by :\n\n{1} \n\nSincerely \XXX Team
     //event.validation.subject=ERROR: Validation error found for booking <{0}>
            //参数变量 
            Object[] paras = {bookingNo};
            String subject = mesgHelper.getMessage("event.validation.subject", paras, null);
            //参数变量 
            Object[] params = { mesgKeys, mailBody};
            String content = mesgHelper.getMessage("event.validation.content", params, null);
           
            MailUtils.sendMail(auoExOp,from,subject,content,to);
        };
    }

 

 
posted on 2019-07-30 17:48  lshan  阅读(1302)  评论(0编辑  收藏  举报