#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中被定義並賦值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對象.
靈活運用吧.web