springMacroRequestContext定义

12 篇文章 0 订阅
6 篇文章 0 订阅

    <#macro m code>${springMacroRequestContext.getMessage(code)}</#macro>

   最近一直想知道springmvc中的这个内置对象springMacroRequestContext是如何来的,最后查看远代码,终于找到AbstractTemplateView

   代码来自http://www.just4e.com/spring-3.1.0/xref/org/springframework/web/servlet/view/AbstractTemplateView.html

    publicstaticfinal String SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE = "springMacroRequestContext";


......


  • if (this.exposeSpringMacroHelpers) {
  • 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.
  • model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
  • newRequestContext(request, response, getServletContext(), model));
  • }


  /*
   * Copyright 2002-2009 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.springframework.web.servlet.view;
  
  import java.util.Enumeration;
  import java.util.Map;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  
  import org.springframework.web.servlet.support.RequestContext;
  
  /**
   * Adapter base class for template-based view technologies such as
   * Velocity and FreeMarker, with the ability to use request and session
   * attributes in their model and the option to expose helper objects
   * for Spring's Velocity/FreeMarker macro library.
   *
   * <p>JSP/JSTL and other view technologies automatically have access to the
   * HttpServletRequest object and thereby the request/session attributes
   * for the current user. Furthermore, they are able to create and cache
   * helper objects as request attributes themselves.
   *
   * @author Juergen Hoeller
   * @author Darren Davison
   * @since 1.0.2
   * @see AbstractTemplateViewResolver
   * @see org.springframework.web.servlet.view.velocity.VelocityView
   * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView
   */
  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";
  
  
  	private boolean exposeRequestAttributes = false;
  
  	private boolean allowRequestOverride = false;
  
  	private boolean exposeSessionAttributes = false;
  
  	private boolean allowSessionOverride = false;
  
  	private boolean exposeSpringMacroHelpers = true;
  
  
  	/**
  	 * Set whether all request attributes should be added to the
  	 * model prior to merging with the template. Default is "false".
  	 */
  	public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
  		this.exposeRequestAttributes = exposeRequestAttributes;
  	}
  
  	/**
  	 * Set whether HttpServletRequest attributes are allowed to override (hide)
  	 * controller generated model attributes of the same name. Default is "false",
  	 * which causes an exception to be thrown if request attributes of the same
  	 * name as model attributes are found.
  	 */
  	public void setAllowRequestOverride(boolean allowRequestOverride) {
  		this.allowRequestOverride = allowRequestOverride;
  	}
  
  	/**
  	 * Set whether all HttpSession attributes should be added to the
  	 * model prior to merging with the template. Default is "false".
  	 */
  	public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
  		this.exposeSessionAttributes = exposeSessionAttributes;
  	}
  
  	/**
  	 * Set whether HttpSession attributes are allowed to override (hide)
  	 * controller generated model attributes of the same name. Default is "false",
  	 * which causes an exception to be thrown if session attributes of the same
  	 * name as model attributes are found.
  	 */
  	public void setAllowSessionOverride(boolean allowSessionOverride) {
  		this.allowSessionOverride = allowSessionOverride;
  	}
  
  	/**
  	 * Set whether to expose a RequestContext for use by Spring's macro library,
  	 * under the name "springMacroRequestContext". Default is "true".
  	 * <p>Currently needed for Spring's Velocity and FreeMarker default macros.
  	 * Note that this is <i>not</i> required for templates that use HTML
  	 * forms <i>unless</i> you wish to take advantage of the Spring helper macros.
  	 * @see #SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE
  	 */
  	public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
  		this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
  	}
  
  
  	@Override
  	protected final void renderMergedOutputModel(
  			Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
  
  		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);
  			}
  		}
  
  		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);
  				}
  			}
  		}
  
  		if (this.exposeSpringMacroHelpers) {
  			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.
  			model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
  					new RequestContext(request, response, getServletContext(), model));
  		}
  
  		applyContentType(response);
  
  		renderMergedTemplateModel(model, request, response);
  	}
  
  	/**
  	 * Apply this view's content type as specified in the "contentType"
  	 * bean property to the given response.
  	 * <p>When running on Servlet 2.4, only applies the view's contentType
  	 * if no content type has been set on the response before. This allows
  	 * handlers to override the default content type beforehand.
  	 * @param response current HTTP response
  	 * @see #setContentType
  	 */
  	protected void applyContentType(HttpServletResponse response)	{
  		if (response.getContentType() == null) {
  			response.setContentType(getContentType());
  		}
  	}
  
  	/**
  	 * Subclasses must implement this method to actually render the view.
  	 * @param model combined output Map, with request attributes and
  	 * session attributes merged into it if required
  	 * @param request current HTTP request
  	 * @param response current HTTP response
  	 * @throws Exception if rendering failed
  	 */
  	protected abstract void renderMergedTemplateModel(
  			Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
  
  }


因为

model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,new RequestContext(request, response, getServletContext(), model));

       http://www.just4e.com/spring-3.1.0/xref/org/springframework/web/servlet/support/RequestContext.html


   找到 RequestContext

  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @param defaultMessage String to return if the lookup fails
  • * @return the message
  • */
  • public String getMessage(String code, String defaultMessage) {
  • return getMessage(code, null, defaultMessage, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @param args arguments for the message, or <code>null</code> if none
  • * @param defaultMessage String to return if the lookup fails
  • * @return the message
  • */
  • public String getMessage(String code, Object[] args, String defaultMessage) {
  • return getMessage(code, args, defaultMessage, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @param args arguments for the message as a List, or <code>null</code> if none
  • * @param defaultMessage String to return if the lookup fails
  • * @return the message
  • */
  • public String getMessage(String code, List args, String defaultMessage) {
  • return getMessage(code, (args != null ? args.toArray() : null), defaultMessage, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code.
  • * @param code code of the message
  • * @param args arguments for the message, or <code>null</code> if none
  • * @param defaultMessage String to return if the lookup fails
  • * @param htmlEscape HTML escape the message?
  • * @return the message
  • */
  • public String getMessage(String code, Object[] args, String defaultMessage, boolean htmlEscape) {
  • String msg = this.webApplicationContext.getMessage(code, args, defaultMessage, this.locale);
  • return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  • }
  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(String code) throws NoSuchMessageException {
  • return getMessage(code, null, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @param args arguments for the message, or <code>null</code> if none
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(String code, Object[] args) throws NoSuchMessageException {
  • return getMessage(code, args, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  • * @param code code of the message
  • * @param args arguments for the message as a List, or <code>null</code> if none
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(String code, List args) throws NoSuchMessageException {
  • return getMessage(code, (args != null ? args.toArray() : null), isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the message for the given code.
  • * @param code code of the message
  • * @param args arguments for the message, or <code>null</code> if none
  • * @param htmlEscape HTML escape the message?
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(String code, Object[] args, boolean htmlEscape) throws NoSuchMessageException {
  • String msg = this.webApplicationContext.getMessage(code, args, this.locale);
  • return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  • }
  • /**
  • * Retrieve the given MessageSourceResolvable (e.g. an ObjectError instance),
  • * using the "defaultHtmlEscape" setting.
  • * @param resolvable the MessageSourceResolvable
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(MessageSourceResolvable resolvable) throws NoSuchMessageException {
  • return getMessage(resolvable, isDefaultHtmlEscape());
  • }
  • /**
  • * Retrieve the given MessageSourceResolvable (e.g. an ObjectError instance).
  • * @param resolvable the MessageSourceResolvable
  • * @param htmlEscape HTML escape the message?
  • * @return the message
  • * @throws org.springframework.context.NoSuchMessageException if not found
  • */
  • public String getMessage(MessageSourceResolvable resolvable, boolean htmlEscape) throws NoSuchMessageException {
  • String msg = this.webApplicationContext.getMessage(resolvable, this.locale);
  • return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  • }


  /*
   * Copyright 2002-2010 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.springframework.web.servlet.support;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Locale;
  import java.util.Map;
  import javax.servlet.ServletContext;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  import javax.servlet.jsp.jstl.core.Config;
  
  import org.springframework.context.MessageSource;
  import org.springframework.context.MessageSourceResolvable;
  import org.springframework.context.NoSuchMessageException;
  import org.springframework.ui.context.Theme;
  import org.springframework.ui.context.ThemeSource;
  import org.springframework.ui.context.support.ResourceBundleThemeSource;
  import org.springframework.util.Assert;
  import org.springframework.util.ClassUtils;
  import org.springframework.validation.BindException;
  import org.springframework.validation.BindingResult;
  import org.springframework.validation.Errors;
  import org.springframework.web.bind.EscapedErrors;
  import org.springframework.web.context.WebApplicationContext;
  import org.springframework.web.servlet.LocaleResolver;
  import org.springframework.web.util.HtmlUtils;
  import org.springframework.web.util.UrlPathHelper;
  import org.springframework.web.util.WebUtils;
  
  /**
   * Context holder for request-specific state, like current web application
   * context, current locale, current theme, and potential binding errors.
   * Provides easy access to localized messages and Errors instances.
   *
   * <p>Suitable for exposition to views, and usage within JSP's "useBean" tag,
   * JSP scriptlets, JSTL EL, Velocity templates, etc. Necessary for views
   * that do not have access to the servlet request, like Velocity templates.
   *
   * <p>Can be instantiated manually, or automatically exposed to views as
   * model attribute via AbstractView's "requestContextAttribute" property.
   *
   * <p>Will also work outside of DispatcherServlet requests, accessing the root
   * WebApplicationContext and using an appropriate fallback for the locale
   * (the HttpServletRequest's primary locale).
   *
   * @author Juergen Hoeller
   * @since 03.03.2003
   * @see org.springframework.web.servlet.DispatcherServlet
   * @see org.springframework.web.servlet.view.AbstractView#setRequestContextAttribute
   * @see org.springframework.web.servlet.view.UrlBasedViewResolver#setRequestContextAttribute
   * @see #getFallbackLocale()
   */
  public class RequestContext {
  
  	/**
  	 * Default theme name used if the RequestContext cannot find a ThemeResolver.
  	 * Only applies to non-DispatcherServlet requests.
  	 * <p>Same as AbstractThemeResolver's default, but not linked in here to
  	 * avoid package interdependencies.
  	 * @see org.springframework.web.servlet.theme.AbstractThemeResolver#ORIGINAL_DEFAULT_THEME_NAME
  	 */
  	public static final String DEFAULT_THEME_NAME = "theme";
  
  	/**
  	 * Request attribute to hold the current web application context for RequestContext usage.
  	 * By default, the DispatcherServlet's context (or the root context as fallback) is exposed.
  	 */
  	public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = RequestContext.class.getName() + ".CONTEXT";
  
  
  	protected static final boolean jstlPresent = ClassUtils.isPresent(
  			"javax.servlet.jsp.jstl.core.Config", RequestContext.class.getClassLoader());
  
  
  	private HttpServletRequest request;
  
  	private HttpServletResponse response;
  
  	private Map<String, Object> model;
  
  	private WebApplicationContext webApplicationContext;
  
  	private Locale locale;
  
  	private Theme theme;
  
  	private Boolean defaultHtmlEscape;
  
  	private UrlPathHelper urlPathHelper;
  
  	private Map<String, Errors> errorsMap;
  
  
  	/**
  	 * Create a new RequestContext for the given request,
  	 * using the request attributes for Errors retrieval.
  	 * <p>This only works with InternalResourceViews, as Errors instances
  	 * are part of the model and not normally exposed as request attributes.
  	 * It will typically be used within JSPs or custom tags.
  	 * <p><b>Will only work within a DispatcherServlet request.</b> Pass in a
  	 * ServletContext to be able to fallback to the root WebApplicationContext.
  	 * @param request current HTTP request
  	 * @see org.springframework.web.servlet.DispatcherServlet
  	 * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext)
  	 */
  	public RequestContext(HttpServletRequest request) {
  		initContext(request, null, null, null);
  	}
  
  	/**
  	 * Create a new RequestContext for the given request,
  	 * using the request attributes for Errors retrieval.
  	 * <p>This only works with InternalResourceViews, as Errors instances
  	 * are part of the model and not normally exposed as request attributes.
  	 * It will typically be used within JSPs or custom tags.
  	 * <p>If a ServletContext is specified, the RequestContext will also
  	 * work with the root WebApplicationContext (outside a DispatcherServlet).
  	 * @param request current HTTP request
  	 * @param servletContext the servlet context of the web application
  	 * (can be <code>null</code>; necessary for fallback to root WebApplicationContext)
  	 * @see org.springframework.web.context.WebApplicationContext
  	 * @see org.springframework.web.servlet.DispatcherServlet
  	 */
  	public RequestContext(HttpServletRequest request, ServletContext servletContext) {
  		initContext(request, null, servletContext, null);
  	}
  
  	/**
  	 * Create a new RequestContext for the given request,
  	 * using the given model attributes for Errors retrieval.
  	 * <p>This works with all View implementations.
  	 * It will typically be used by View implementations.
  	 * <p><b>Will only work within a DispatcherServlet request.</b> Pass in a
  	 * ServletContext to be able to fallback to the root WebApplicationContext.
  	 * @param request current HTTP request
  	 * @param model the model attributes for the current view
  	 * (can be <code>null</code>, using the request attributes for Errors retrieval)
  	 * @see org.springframework.web.servlet.DispatcherServlet
  	 * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext, Map)
  	 */
  	public RequestContext(HttpServletRequest request, Map<String, Object> model) {
  		initContext(request, null, null, model);
  	}
  
  	/**
  	 * Create a new RequestContext for the given request,
  	 * using the given model attributes for Errors retrieval.
  	 * <p>This works with all View implementations.
  	 * It will typically be used by View implementations.
  	 * <p>If a ServletContext is specified, the RequestContext will also
  	 * work with a root WebApplicationContext (outside a DispatcherServlet).
  	 * @param request current HTTP request
  	 * @param response current HTTP response
  	 * @param servletContext the servlet context of the web application
  	 * (can be <code>null</code>; necessary for fallback to root WebApplicationContext)
  	 * @param model the model attributes for the current view
  	 * (can be <code>null</code>, using the request attributes for Errors retrieval)
  	 * @see org.springframework.web.context.WebApplicationContext
  	 * @see org.springframework.web.servlet.DispatcherServlet
  	 */
  	public RequestContext(HttpServletRequest request, HttpServletResponse response,
  			ServletContext servletContext, Map<String, Object> model) {
  
  		initContext(request, response, servletContext, model);
  	}
  
  	/**
  	 * Default constructor for subclasses.
  	 */
  	protected RequestContext() {
  	}
  
  
  	/**
  	 * Initialize this context with the given request,
  	 * using the given model attributes for Errors retrieval.
  	 * <p>Delegates to <code>getFallbackLocale</code> and <code>getFallbackTheme</code>
  	 * for determining the fallback locale and theme, respectively, if no LocaleResolver
  	 * and/or ThemeResolver can be found in the request.
  	 * @param request current HTTP request
  	 * @param servletContext the servlet context of the web application
  	 * (can be <code>null</code>; necessary for fallback to root WebApplicationContext)
  	 * @param model the model attributes for the current view
  	 * (can be <code>null</code>, using the request attributes for Errors retrieval)
  	 * @see #getFallbackLocale
  	 * @see #getFallbackTheme
  	 * @see org.springframework.web.servlet.DispatcherServlet#LOCALE_RESOLVER_ATTRIBUTE
  	 * @see org.springframework.web.servlet.DispatcherServlet#THEME_RESOLVER_ATTRIBUTE
  	 */
  	protected void initContext(HttpServletRequest request, HttpServletResponse response,
  			ServletContext servletContext, Map<String, Object> model) {
  
  		this.request = request;
  		this.response = response;
  		this.model = model;
  
  		// Fetch WebApplicationContext, either from DispatcherServlet or the root context.
  		// ServletContext needs to be specified to be able to fall back to the root context!
  		this.webApplicationContext =
  				(WebApplicationContext) request.getAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  		if (this.webApplicationContext == null) {
  			this.webApplicationContext = RequestContextUtils.getWebApplicationContext(request, servletContext);
  		}
  
  		// Determine locale to use for this RequestContext.
  		LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
  		if (localeResolver != null) {
  			// Try LocaleResolver (we're within a DispatcherServlet request).
  			this.locale = localeResolver.resolveLocale(request);
  		}
  		else {
  			// No LocaleResolver available -> try fallback.
  			this.locale = getFallbackLocale();
  		}
  
  		// Determine default HTML escape setting from the "defaultHtmlEscape"
  		// context-param in web.xml, if any.
  		this.defaultHtmlEscape = WebUtils.getDefaultHtmlEscape(this.webApplicationContext.getServletContext());
  
  		this.urlPathHelper = new UrlPathHelper();
  	}
  
  	/**
  	 * Determine the fallback locale for this context.
  	 * <p>The default implementation checks for a JSTL locale attribute
  	 * in request, session or application scope; if not found,
  	 * returns the <code>HttpServletRequest.getLocale()</code>.
  	 * @return the fallback locale (never <code>null</code>)
  	 * @see javax.servlet.http.HttpServletRequest#getLocale()
  	 */
  	protected Locale getFallbackLocale() {
  		if (jstlPresent) {
  			Locale locale = JstlLocaleResolver.getJstlLocale(getRequest(), getServletContext());
  			if (locale != null) {
  				return locale;
  			}
  		}
  		return getRequest().getLocale();
  	}
  
  	/**
  	 * Determine the fallback theme for this context.
  	 * <p>The default implementation returns the default theme (with name "theme").
  	 * @return the fallback theme (never <code>null</code>)
  	 */
  	protected Theme getFallbackTheme() {
  		ThemeSource themeSource = RequestContextUtils.getThemeSource(getRequest());
  		if (themeSource == null) {
  			themeSource = new ResourceBundleThemeSource();
  		}
  		Theme theme = themeSource.getTheme(DEFAULT_THEME_NAME);
  		if (theme == null) {
  			throw new IllegalStateException("No theme defined and no fallback theme found");
  		}
  		return theme;
  	}
  
  
  	/**
  	 * Return the underlying HttpServletRequest.
  	 * Only intended for cooperating classes in this package.
  	 */
  	protected final HttpServletRequest getRequest() {
  		return this.request;
  	}
  
  	/**
  	 * Return the underlying ServletContext.
  	 * Only intended for cooperating classes in this package.
  	 */
  	protected final ServletContext getServletContext() {
  		return this.webApplicationContext.getServletContext();
  	}
  
  	/**
  	 * Return the current WebApplicationContext.
  	 */
  	public final WebApplicationContext getWebApplicationContext() {
  		return this.webApplicationContext;
  	}
  
  	/**
  	 * Return the current WebApplicationContext as MessageSource.
  	 */
  	public final MessageSource getMessageSource() {
  		return this.webApplicationContext;
  	}
  
  	/**
  	 * Return the model Map that this RequestContext encapsulates, if any.
  	 * @return the populated model Map, or <code>null</code> if none available
  	 */
  	public final Map<String, Object> getModel() {
  		return this.model;
  	}
  
  	/**
  	 * Return the current Locale (never <code>null</code>).
  	 */
  	public final Locale getLocale() {
  		return this.locale;
  	}
  
  	/**
  	 * Return the current theme (never <code>null</code>).
  	 * <p>Resolved lazily for more efficiency when theme support is not being used.
  	 */
  	public final Theme getTheme() {
  		if (this.theme == null) {
  			// Lazily determine theme to use for this RequestContext.
  			this.theme = RequestContextUtils.getTheme(this.request);
  			if (this.theme == null) {
  				// No ThemeResolver and ThemeSource available -> try fallback.
  				this.theme = getFallbackTheme();
  			}
  		}
  		return this.theme;
  	}
  
  
  	/**
  	 * (De)activate default HTML escaping for messages and errors, for the scope
  	 * of this RequestContext. The default is the application-wide setting
  	 * (the "defaultHtmlEscape" context-param in web.xml).
  	 * @see org.springframework.web.util.WebUtils#isDefaultHtmlEscape
  	 */
  	public void setDefaultHtmlEscape(boolean defaultHtmlEscape) {
  		this.defaultHtmlEscape = defaultHtmlEscape;
  	}
  
  	/**
  	 * Is default HTML escaping active?
  	 * Falls back to <code>false</code> in case of no explicit default given.
  	 */
  	public boolean isDefaultHtmlEscape() {
  		return (this.defaultHtmlEscape != null && this.defaultHtmlEscape.booleanValue());
  	}
  
  	/**
  	 * Return the default HTML escape setting, differentiating
  	 * between no default specified and an explicit value.
  	 * @return whether default HTML escaping is enabled (null = no explicit default)
  	 */
  	public Boolean getDefaultHtmlEscape() {
  		return this.defaultHtmlEscape;
  	}
  
  	/**
  	 * Set the UrlPathHelper to use for context path and request URI decoding.
  	 * Can be used to pass a shared UrlPathHelper instance in.
  	 * <p>A default UrlPathHelper is always available.
  	 */
  	public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
  		Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
  		this.urlPathHelper = urlPathHelper;
  	}
  
  	/**
  	 * Return the UrlPathHelper used for context path and request URI decoding.
  	 * Can be used to configure the current UrlPathHelper.
  	 * <p>A default UrlPathHelper is always available.
  	 */
  	public UrlPathHelper getUrlPathHelper() {
  		return this.urlPathHelper;
  	}
  
  
  	/**
  	 * Return the context path of the original request,
  	 * that is, the path that indicates the current web application.
  	 * This is useful for building links to other resources within the application.
  	 * <p>Delegates to the UrlPathHelper for decoding.
  	 * @see javax.servlet.http.HttpServletRequest#getContextPath
  	 * @see #getUrlPathHelper
  	 */
  	public String getContextPath() {
  		return this.urlPathHelper.getOriginatingContextPath(this.request);
  	}
  
  	/**
  	 * Return a context-aware URl for the given relative URL.
  	 * @param relativeUrl the relative URL part
  	 * @return a URL that points back to the server with an absolute path
  	 * (also URL-encoded accordingly)
  	 */
  	public String getContextUrl(String relativeUrl) {
  		String url = getContextPath() + relativeUrl;
  		if (this.response != null) {
  			url = this.response.encodeURL(url);
  		}
  		return url;
  	}
  
  	/**
  	 * Return the request URI of the original request, that is, the invoked URL
  	 * without parameters. This is particularly useful as HTML form action target,
  	 * possibly in combination with the original query string.
  	 * <p><b>Note this implementation will correctly resolve to the URI of any
  	 * originating root request in the presence of a forwarded request. However, this
  	 * can only work when the Servlet 2.4 'forward' request attributes are present.
  	 * <p>Delegates to the UrlPathHelper for decoding.
  	 * @see #getQueryString
  	 * @see org.springframework.web.util.UrlPathHelper#getOriginatingRequestUri
  	 * @see #getUrlPathHelper
  	 */
  	public String getRequestUri() {
  		return this.urlPathHelper.getOriginatingRequestUri(this.request);
  	}
  
  	/**
  	 * Return the query string of the current request, that is, the part after
  	 * the request path. This is particularly useful for building an HTML form
  	 * action target in combination with the original request URI.
  	 * <p><b>Note this implementation will correctly resolve to the query string of any
  	 * originating root request in the presence of a forwarded request. However, this
  	 * can only work when the Servlet 2.4 'forward' request attributes are present.
  	 * <p>Delegates to the UrlPathHelper for decoding.
  	 * @see #getRequestUri
  	 * @see org.springframework.web.util.UrlPathHelper#getOriginatingQueryString
  	 * @see #getUrlPathHelper
  	 */
  	public String getQueryString() {
  		return this.urlPathHelper.getOriginatingQueryString(this.request);
  	}
  
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getMessage(String code, String defaultMessage) {
  		return getMessage(code, null, defaultMessage, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getMessage(String code, Object[] args, String defaultMessage) {
  		return getMessage(code, args, defaultMessage, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @param args arguments for the message as a List, or <code>null</code> if none
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getMessage(String code, List args, String defaultMessage) {
  		return getMessage(code, (args != null ? args.toArray() : null), defaultMessage, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @param defaultMessage String to return if the lookup fails
  	 * @param htmlEscape HTML escape the message?
  	 * @return the message
  	 */
  	public String getMessage(String code, Object[] args, String defaultMessage, boolean htmlEscape) {
  		String msg = this.webApplicationContext.getMessage(code, args, defaultMessage, this.locale);
  		return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  	}
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(String code) throws NoSuchMessageException {
  		return getMessage(code, null, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(String code, Object[] args) throws NoSuchMessageException {
  		return getMessage(code, args, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code, using the "defaultHtmlEscape" setting.
  	 * @param code code of the message
  	 * @param args arguments for the message as a List, or <code>null</code> if none
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(String code, List args) throws NoSuchMessageException {
  		return getMessage(code, (args != null ? args.toArray() : null), isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the message for the given code.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @param htmlEscape HTML escape the message?
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(String code, Object[] args, boolean htmlEscape) throws NoSuchMessageException {
  		String msg = this.webApplicationContext.getMessage(code, args, this.locale);
  		return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  	}
  
  	/**
  	 * Retrieve the given MessageSourceResolvable (e.g. an ObjectError instance),
  	 * using the "defaultHtmlEscape" setting.
  	 * @param resolvable the MessageSourceResolvable
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(MessageSourceResolvable resolvable) throws NoSuchMessageException {
  		return getMessage(resolvable, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the given MessageSourceResolvable (e.g. an ObjectError instance).
  	 * @param resolvable the MessageSourceResolvable
  	 * @param htmlEscape HTML escape the message?
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getMessage(MessageSourceResolvable resolvable, boolean htmlEscape) throws NoSuchMessageException {
  		String msg = this.webApplicationContext.getMessage(resolvable, this.locale);
  		return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
  	}
  
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getThemeMessage(String code, String defaultMessage) {
  		return getTheme().getMessageSource().getMessage(code, null, defaultMessage, this.locale);
  	}
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getThemeMessage(String code, Object[] args, String defaultMessage) {
  		return getTheme().getMessageSource().getMessage(code, args, defaultMessage, this.locale);
  	}
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @param args arguments for the message as a List, or <code>null</code> if none
  	 * @param defaultMessage String to return if the lookup fails
  	 * @return the message
  	 */
  	public String getThemeMessage(String code, List args, String defaultMessage) {
  		return getTheme().getMessageSource().getMessage(
  				code, (args != null ? args.toArray() : null), defaultMessage, this.locale);
  	}
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getThemeMessage(String code) throws NoSuchMessageException {
  		return getTheme().getMessageSource().getMessage(code, null, this.locale);
  	}
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @param args arguments for the message, or <code>null</code> if none
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getThemeMessage(String code, Object[] args) throws NoSuchMessageException {
  		return getTheme().getMessageSource().getMessage(code, args, this.locale);
  	}
  
  	/**
  	 * Retrieve the theme message for the given code.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param code code of the message
  	 * @param args arguments for the message as a List, or <code>null</code> if none
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getThemeMessage(String code, List args) throws NoSuchMessageException {
  		return getTheme().getMessageSource().getMessage(
  				code, (args != null ? args.toArray() : null), this.locale);
  	}
  
  	/**
  	 * Retrieve the given MessageSourceResolvable in the current theme.
  	 * <p>Note that theme messages are never HTML-escaped, as they typically
  	 * denote theme-specific resource paths and not client-visible messages.
  	 * @param resolvable the MessageSourceResolvable
  	 * @return the message
  	 * @throws org.springframework.context.NoSuchMessageException if not found
  	 */
  	public String getThemeMessage(MessageSourceResolvable resolvable) throws NoSuchMessageException {
  		return getTheme().getMessageSource().getMessage(resolvable, this.locale);
  	}
  
  
  	/**
  	 * Retrieve the Errors instance for the given bind object,
  	 * using the "defaultHtmlEscape" setting.
  	 * @param name name of the bind object
  	 * @return the Errors instance, or <code>null</code> if not found
  	 */
  	public Errors getErrors(String name) {
  		return getErrors(name, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Retrieve the Errors instance for the given bind object.
  	 * @param name name of the bind object
  	 * @param htmlEscape create an Errors instance with automatic HTML escaping?
  	 * @return the Errors instance, or <code>null</code> if not found
  	 */
  	public Errors getErrors(String name, boolean htmlEscape) {
  		if (this.errorsMap == null) {
  			this.errorsMap = new HashMap<String, Errors>();
  		}
  		Errors errors = this.errorsMap.get(name);
  		boolean put = false;
  		if (errors == null) {
  			errors = (Errors) getModelObject(BindingResult.MODEL_KEY_PREFIX + name);
  			// Check old BindException prefix for backwards compatibility.
  			if (errors instanceof BindException) {
  				errors = ((BindException) errors).getBindingResult();
  			}
  			if (errors == null) {
  				return null;
  			}
  			put = true;
  		}
  		if (htmlEscape && !(errors instanceof EscapedErrors)) {
  			errors = new EscapedErrors(errors);
  			put = true;
  		}
  		else if (!htmlEscape && errors instanceof EscapedErrors) {
  			errors = ((EscapedErrors) errors).getSource();
  			put = true;
  		}
  		if (put) {
  			this.errorsMap.put(name, errors);
  		}
  		return errors;
  	}
  
  	/**
  	 * Retrieve the model object for the given model name,
  	 * either from the model or from the request attributes.
  	 * @param modelName the name of the model object
  	 * @return the model object
  	 */
  	protected Object getModelObject(String modelName) {
  		if (this.model != null) {
  			return this.model.get(modelName);
  		}
  		else {
  			return this.request.getAttribute(modelName);
  		}
  	}
  
  	/**
  	 * Create a BindStatus for the given bind object,
  	 * using the "defaultHtmlEscape" setting.
  	 * @param path the bean and property path for which values and errors
  	 * will be resolved (e.g. "person.age")
  	 * @return the new BindStatus instance
  	 * @throws IllegalStateException if no corresponding Errors object found
  	 */
  	public BindStatus getBindStatus(String path) throws IllegalStateException {
  		return new BindStatus(this, path, isDefaultHtmlEscape());
  	}
  
  	/**
  	 * Create a BindStatus for the given bind object,
  	 * using the "defaultHtmlEscape" setting.
  	 * @param path the bean and property path for which values and errors
  	 * will be resolved (e.g. "person.age")
  	 * @param htmlEscape create a BindStatus with automatic HTML escaping?
  	 * @return the new BindStatus instance
  	 * @throws IllegalStateException if no corresponding Errors object found
  	 */
  	public BindStatus getBindStatus(String path, boolean htmlEscape) throws IllegalStateException {
  		return new BindStatus(this, path, htmlEscape);
  	}
  
  
  	/**
  	 * Inner class that isolates the JSTL dependency.
  	 * Just called to resolve the fallback locale if the JSTL API is present.
  	 */
  	private static class JstlLocaleResolver {
  
  		public static Locale getJstlLocale(HttpServletRequest request, ServletContext servletContext) {
  			Object localeObject = Config.get(request, Config.FMT_LOCALE);
  			if (localeObject == null) {
  				HttpSession session = request.getSession(false);
  				if (session != null) {
  					localeObject = Config.get(session, Config.FMT_LOCALE);
  				}
  				if (localeObject == null && servletContext != null) {
  					localeObject = Config.get(servletContext, Config.FMT_LOCALE);
  				}
  			}
  			return (localeObject instanceof Locale ? (Locale) localeObject : null);
  		}
  	}
  
  }


public interface WebApplicationContext extends ApplicationContext




    <#macro m code>${springMacroRequestContext.getMessage(code)}</#macro>


  通过这2个类终于找到答案了


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值