/*
 * Copyright 2002-2017 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.i18n;

import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.TimeZoneAwareLocaleContext;
import org.springframework.lang.Nullable;
import org.springframework.web.util.WebUtils;

LocaleResolver implementation that uses a locale attribute in the user's session in case of a custom setting, with a fallback to the specified default locale or the request's accept-header locale.

This is most appropriate if the application needs user sessions anyway, i.e. when the HttpSession does not have to be created just for storing the user's locale. The session may optionally contain an associated time zone attribute as well; alternatively, you may specify a default time zone.

Custom controllers can override the user's locale and time zone by calling #setLocale(Context) on the resolver, e.g. responding to a locale change request. As a more convenient alternative, consider using RequestContext.changeLocale.

In contrast to CookieLocaleResolver, this strategy stores locally chosen locale settings in the Servlet container's HttpSession. As a consequence, those settings are just temporary for each session and therefore lost when each session terminates.

Note that there is no direct relationship with external session management mechanisms such as the "Spring Session" project. This LocaleResolver will simply evaluate and modify corresponding HttpSession attributes against the current HttpServletRequest.

Author:Juergen Hoeller
See Also:
Since:27.02.2003
/** * {@link org.springframework.web.servlet.LocaleResolver} implementation that * uses a locale attribute in the user's session in case of a custom setting, * with a fallback to the specified default locale or the request's * accept-header locale. * * <p>This is most appropriate if the application needs user sessions anyway, * i.e. when the {@code HttpSession} does not have to be created just for storing * the user's locale. The session may optionally contain an associated time zone * attribute as well; alternatively, you may specify a default time zone. * * <p>Custom controllers can override the user's locale and time zone by calling * {@code #setLocale(Context)} on the resolver, e.g. responding to a locale change * request. As a more convenient alternative, consider using * {@link org.springframework.web.servlet.support.RequestContext#changeLocale}. * * <p>In contrast to {@link CookieLocaleResolver}, this strategy stores locally * chosen locale settings in the Servlet container's {@code HttpSession}. As a * consequence, those settings are just temporary for each session and therefore * lost when each session terminates. * * <p>Note that there is no direct relationship with external session management * mechanisms such as the "Spring Session" project. This {@code LocaleResolver} * will simply evaluate and modify corresponding {@code HttpSession} attributes * against the current {@code HttpServletRequest}. * * @author Juergen Hoeller * @since 27.02.2003 * @see #setDefaultLocale * @see #setDefaultTimeZone */
public class SessionLocaleResolver extends AbstractLocaleContextResolver {
Name of the session attribute that holds the Locale. Only used internally by this implementation.

Use RequestContext(Utils).getLocale() to retrieve the current locale in controllers or views.

See Also:
/** * Name of the session attribute that holds the Locale. * Only used internally by this implementation. * <p>Use {@code RequestContext(Utils).getLocale()} * to retrieve the current locale in controllers or views. * @see org.springframework.web.servlet.support.RequestContext#getLocale * @see org.springframework.web.servlet.support.RequestContextUtils#getLocale */
public static final String LOCALE_SESSION_ATTRIBUTE_NAME = SessionLocaleResolver.class.getName() + ".LOCALE";
Name of the session attribute that holds the TimeZone. Only used internally by this implementation.

Use RequestContext(Utils).getTimeZone() to retrieve the current time zone in controllers or views.

See Also:
/** * Name of the session attribute that holds the TimeZone. * Only used internally by this implementation. * <p>Use {@code RequestContext(Utils).getTimeZone()} * to retrieve the current time zone in controllers or views. * @see org.springframework.web.servlet.support.RequestContext#getTimeZone * @see org.springframework.web.servlet.support.RequestContextUtils#getTimeZone */
public static final String TIME_ZONE_SESSION_ATTRIBUTE_NAME = SessionLocaleResolver.class.getName() + ".TIME_ZONE"; private String localeAttributeName = LOCALE_SESSION_ATTRIBUTE_NAME; private String timeZoneAttributeName = TIME_ZONE_SESSION_ATTRIBUTE_NAME;
Specify the name of the corresponding attribute in the HttpSession, holding the current Locale value.

The default is an internal LOCALE_SESSION_ATTRIBUTE_NAME.

Since:4.3.8
/** * Specify the name of the corresponding attribute in the {@code HttpSession}, * holding the current {@link Locale} value. * <p>The default is an internal {@link #LOCALE_SESSION_ATTRIBUTE_NAME}. * @since 4.3.8 */
public void setLocaleAttributeName(String localeAttributeName) { this.localeAttributeName = localeAttributeName; }
Specify the name of the corresponding attribute in the HttpSession, holding the current TimeZone value.

The default is an internal TIME_ZONE_SESSION_ATTRIBUTE_NAME.

Since:4.3.8
/** * Specify the name of the corresponding attribute in the {@code HttpSession}, * holding the current {@link TimeZone} value. * <p>The default is an internal {@link #TIME_ZONE_SESSION_ATTRIBUTE_NAME}. * @since 4.3.8 */
public void setTimeZoneAttributeName(String timeZoneAttributeName) { this.timeZoneAttributeName = timeZoneAttributeName; } @Override public Locale resolveLocale(HttpServletRequest request) { Locale locale = (Locale) WebUtils.getSessionAttribute(request, this.localeAttributeName); if (locale == null) { locale = determineDefaultLocale(request); } return locale; } @Override public LocaleContext resolveLocaleContext(final HttpServletRequest request) { return new TimeZoneAwareLocaleContext() { @Override public Locale getLocale() { Locale locale = (Locale) WebUtils.getSessionAttribute(request, localeAttributeName); if (locale == null) { locale = determineDefaultLocale(request); } return locale; } @Override @Nullable public TimeZone getTimeZone() { TimeZone timeZone = (TimeZone) WebUtils.getSessionAttribute(request, timeZoneAttributeName); if (timeZone == null) { timeZone = determineDefaultTimeZone(request); } return timeZone; } }; } @Override public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable LocaleContext localeContext) { Locale locale = null; TimeZone timeZone = null; if (localeContext != null) { locale = localeContext.getLocale(); if (localeContext instanceof TimeZoneAwareLocaleContext) { timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone(); } } WebUtils.setSessionAttribute(request, this.localeAttributeName, locale); WebUtils.setSessionAttribute(request, this.timeZoneAttributeName, timeZone); }
Determine the default locale for the given request, Called if no Locale session attribute has been found.

The default implementation returns the specified default locale, if any, else falls back to the request's accept-header locale.

Params:
  • request – the request to resolve the locale for
See Also:
Returns:the default locale (never null)
/** * Determine the default locale for the given request, * Called if no Locale session attribute has been found. * <p>The default implementation returns the specified default locale, * if any, else falls back to the request's accept-header locale. * @param request the request to resolve the locale for * @return the default locale (never {@code null}) * @see #setDefaultLocale * @see javax.servlet.http.HttpServletRequest#getLocale() */
protected Locale determineDefaultLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); if (defaultLocale == null) { defaultLocale = request.getLocale(); } return defaultLocale; }
Determine the default time zone for the given request, Called if no TimeZone session attribute has been found.

The default implementation returns the specified default time zone, if any, or null otherwise.

Params:
  • request – the request to resolve the time zone for
See Also:
Returns:the default time zone (or null if none defined)
/** * Determine the default time zone for the given request, * Called if no TimeZone session attribute has been found. * <p>The default implementation returns the specified default time zone, * if any, or {@code null} otherwise. * @param request the request to resolve the time zone for * @return the default time zone (or {@code null} if none defined) * @see #setDefaultTimeZone */
@Nullable protected TimeZone determineDefaultTimeZone(HttpServletRequest request) { return getDefaultTimeZone(); } }