#springMessage()宏的解惑

#springMessage("xxx")处理国际化:
spring处理国际化的方式可以很特别,因为可以使用这个标记.
这个标记是在spring整合velocity模版后才能使用.这个模版在:
org.springframework.web.servlet\src\main\java\org\springframework\web\servlet\view\velocity\spring.vm
velocity模版中第一个宏就是springMessage标记,还有其他的标记,如果用velocity的话,确实是很方便.
#macro( springMessage $code )$springMacroRequestContext.getMessage($code)#end
在此又有疑惑.因为这个宏用到了$springMacroRequestContext这个东西又是怎么回事呢?
原来这个变量在org.springframework.web.servlet.view.AbstractTemplateView.java中被定义并赋值

public abstract class AbstractTemplateView extends AbstractUrlBasedView {
 /**
  * Variable name of the RequestContext instance in the template model,
  * available to Spring's macros: e.g. for creating BindStatus objects.
  */
 public static final String SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE = "springMacroRequestContext";
 //...略
 //从字面上就能够理解了,渲染宏并输出到model
 protected final void renderMergedOutputModel(
    Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
  //如果配置VelocityViewResolver模版时将此属性设置为true,那么将把request中的属性值放到model中
  if (this.exposeRequestAttributes) { 
    for (Enumeration en = request.getAttributeNames(); en.hasMoreElements();) {
     String attribute = (String) en.nextElement();
     if (model.containsKey(attribute) && !this.allowRequestOverride) {
      throw new ServletException("Cannot expose request attribute '" + attribute +
       "' because of an existing model object of the same name");
     }
     Object attributeValue = request.getAttribute(attribute);
     if (logger.isDebugEnabled()) {
      logger.debug("Exposing request attribute '" + attribute +
        "' with value [" + attributeValue + "] to model");
     }
     model.put(attribute, attributeValue);
    }
   }
   //如果配置VelocityViewResolver模版时将此属性设置为true,那么将把session中的属性值放到model中
   if (this.exposeSessionAttributes) {
    HttpSession session = request.getSession(false);
    if (session != null) {
     for (Enumeration en = session.getAttributeNames(); en.hasMoreElements();) {
      String attribute = (String) en.nextElement();
      if (model.containsKey(attribute) && !this.allowSessionOverride) {
       throw new ServletException("Cannot expose session attribute '" + attribute +
        "' because of an existing model object of the same name");
      }
      Object attributeValue = session.getAttribute(attribute);
      if (logger.isDebugEnabled()) {
       logger.debug("Exposing session attribute '" + attribute +
         "' with value [" + attributeValue + "] to model");
      }
      model.put(attribute, attributeValue);
     }
    }
   }
   //如果宏可以被使用,从VelocityViewResolver的父类AbstractTemplateViewResolver
   //可以得知exposeSpringMacroHelpers默认为true
   if (this.exposeSpringMacroHelpers) {
    //如果model中存在,那么便抛出一个异常,否则
    if (model.containsKey(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE)) {
     throw new ServletException(
       "Cannot expose bind macro helper '" + SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE +
       "' because of an existing model object of the same name");
    }
    // Expose RequestContext instance for Spring macros.
    // 翻译一下:将RequestContext实例对象暴露为宏变量,说直接就是给SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE赋值
    model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
      new RequestContext(request, response, getServletContext(), model));
   }
   applyContentType(response);
   renderMergedTemplateModel(model, request, response);//渲染velocity模版,子类VelocityView会实现
 }

由此在页面中可以使用#springMessage("xxx")来获取资源的代码值.当然在代码中可以看到其实这个宏就是RequestContext对象.
  灵活运用吧.

转载于:https://my.oschina.net/u/870797/blog/364951

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值