📄 requestcontext.java
字号:
/*
* Copyright 2002-2008 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.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", JspAwareRequestContext.class.getClassLoader());
private HttpServletRequest request;
private Map model;
private WebApplicationContext webApplicationContext;
private Locale locale;
private Theme theme;
private Boolean defaultHtmlEscape;
private UrlPathHelper urlPathHelper;
private Map 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);
}
/**
* 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, 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 model) {
initContext(request, 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 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, ServletContext servletContext, Map model) {
initContext(request, 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, ServletContext servletContext, Map model) {
this.request = request;
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 current locale.
*/
public final Locale getLocale() {
return this.locale;
}
/**
* Return the current theme (never <code>null</code>).
* Resolved lazily for more efficiency when theme support is not 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 = Boolean.valueOf(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;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -