首页 > 代码库 > #springMessage宏的根源
#springMessage宏的根源
前提:略了,springMVC的知识
#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对象.
灵活运用吧.
#springMessage宏的根源
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。