template渲染和str+=有什么区别

2025-04-28 23:29:54
推荐回答(1个)
回答1:

  工作中我们经常会遇到这样的需求:
  1.发送一段消息并在web前端展示(例如工作台就是一个很好的场景)
  
  solution 1:
  
  
  Java代码
  String message="xx";
  sender.send(message);
  
  这个方法第一个硬伤,如果xx包含中文或者其他字符呢?
  前端看到的内容可能会出现乱码。
  
  第二个问题,如果message内容更很长,代码的可读性就变得很差了。
  
  solution 2:
  
  Java代码
  String message=MessageResultCode.SHORT_MESSAGE.getMessage();
  sender.send(message);
  既然有中文的问题,我们就使用配置文件,ResultCode可以帮助我们解决这个问题,虽然如果内容长了配置文件
  会有些难看,但也还可以接受。甚至如果内容含有样式,链接,等等,我们也可以通过CDATA来解决。
  
  这个方法暂时看起来不错,不过pd似乎不让我们这么容易的完成任务。“那么我想在消息里显示下链路信息,比如链路名”。这个需求很合理,但是我们的solution 2似乎办不到。
  
  solution 3:
  
  我们知道webx3使用了velocity作为模板渲染引擎,所以何不把消息像velocity模板一样的渲染出来
  
  
  Java代码
  String template="message.vm";
  TemplateContext context = new MappedTemplateContext();
  context.put("link", link);
  context.put("chain", chain);
  //merge模板
  String message = templateService.getText(template, context);
  sender.send(message);
  代码其实很简单,新建一个模板,把所有变量放到context中去,再使用templateService渲染出来。
  我们看看供应链服务一个任务模板的例子:
  
  请审核供应链[$!{chain.name}]编号[$!{chain.id}]-商家[$!{chain.supplierName}]-商品[$!{chain.productTitle}]

那么template路径到底怎么指定呢?这是一个问题。在回答这个问题之前我们看看templateService是如何配置的
  
  
  Java代码
  
  
  
  macros.vm
  

  
  
  
  

  

  

  
  事实上templateService 在渲染vm模板的时候使用velocity引擎来完成的
  我们看看templateService实现类的这个方法
  
  Java代码
  private boolean findTemplateInTemplateEngine(TemplateMatcher matcher) {
  TemplateEngine engine = getTemplateEngine(matcher.getExtension());
  
  matcher.setEngine(engine);
  
  if (engine == null) {
  return false;
  }
  
  String templateName = matcher.getTemplateName();
  
  getLogger().trace("Searching for template \"{}\" using {}", templateName, engine);
  
  return engine.exists(templateName);
  }
  
  所以路径如何设置取决 于TemplateEngine 的path参数。我们看到path="/templates/${component}",${component}这个变量是webx3
  给每个子容器的名字,例如供应链服务叫chain。我们看下pipeline的配置
  
  
  Java代码
  
  
  
  
  
  

  
  renderTemplate这个valve也是使用templateService来渲染模板。
  例如输入的模板名叫screen/detail.vm
  那么 templateService就会找/template/chain/screen/detail.vm这个文件。
  webx3的资源加载使用ResourceLoadingService
  而由于resources.xml文件里有如下配置
  
  
  Java代码
  
  
  

  
  
  因此这个地址也就变成了${alibaba_lp_lpscm_templates}/template/chain/screen/detail.vm,
  ${alibaba_lp_lpscm_templates}是我们antx文件里配置的模板路径。
  这个工作原理适用于web层的东西,biz层使用templateService稍微有点区别,
  因为biz层使用了root容器的templateService因此,$component 的值取决于这段配置
  
  
  
  Java代码
  
  common
  

  因此刚刚那个例子,我们需要把文件放在 ${alibaba_lp_lpscm_templates}/template/common/message.vm.
  当然你也可以修改配置以改变模板的位置,例如把common改成message
  
  
  Java代码
  
  message
  

  
  那么文件需要放在 ${alibaba_lp_lpscm_templates}/template/mesage/message.vm.