好吧,沒有答案,但我主要有這個工作,所以這就是我所做的。我基本上覆制&粘貼大量的CookieLocaleResolver
,因爲有我需要的私人方法,以及其他一些原因。但是我來到了我自己的版本cookie的解析器,並修改了cookie值的格式,以支持更多的參數:
/**
* <p>The custom locale resolver will also handle setting up the customer's local store in the
* locale context.</p>
*
*
*/
public class StoreLocaleResolver extends CookieLocaleResolver {
private static Logger logger = LogManager.getLogger(StoreLocaleResolver.class.getName());
private Location defaultLocation;
private Location location;
@Autowired
private LocationService locationService;
/**
* The name of the request attribute that holds the Location Information.
* <p>Only used for overriding a cookie value if the locale has been
* changed in the course of the current request!
* <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 LOCAL_STORE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".LOCAL_STORE";
@Override
public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {
//super.setLocaleContext(request, response, localeContext);
Locale locale = null;
TimeZone timeZone = null;
Location location = null;
if (localeContext != null) {
removeCookie(response);
if (localeContext instanceof SimpleStoreAwareLocaleContext) {
locale = localeContext.getLocale();
location = ((SimpleStoreAwareLocaleContext) localeContext).getLocation();
timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
}
StringBuilder bud = new StringBuilder();
if (locale != null)
bud.append("locale:" + locale);
if (timeZone != null)
{
bud.append("::");
bud.append("timezone:" + timeZone.getID());
}
if (location != null)
{
bud.append("::");
bud.append("location:" + location.getExternalIdentifier());
}
String cookieValue = bud.toString();
addCookie(response, bud.toString());
}
else {
removeCookie(response);
}
request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
(locale != null ? locale: determineDefaultLocale(request)));
request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
(timeZone != null ? timeZone : determineDefaultTimeZone(request)));
request.setAttribute(LOCAL_STORE_REQUEST_ATTRIBUTE_NAME,
(location != null ? location: determineDefaultLocalStore(request)));
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
SimpleStoreAwareLocaleContext localeContext = new SimpleStoreAwareLocaleContext(locale, null);
Location loc = (Location)request.getAttribute(StoreLocaleResolver.LOCAL_STORE_REQUEST_ATTRIBUTE_NAME);
if (loc != null)
{
localeContext.setLocation(loc);
}
setLocaleContext(request, response, (locale != null ? localeContext : null));
}
@Override
public Locale resolveLocale(HttpServletRequest request) {
parseLocaleCookieIfNecessary(request);
return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
}
@Override
public LocaleContext resolveLocaleContext(final HttpServletRequest request) {
parseLocaleCookieIfNecessary(request);
return new StoreAwareLocaleContext() {
@Override
public Locale getLocale() {
return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
}
@Override
public TimeZone getTimeZone() {
return (TimeZone) request.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME);
}
@Override
public Location getLocation() {
return (Location) request.getAttribute(LOCAL_STORE_REQUEST_ATTRIBUTE_NAME);
}
};
}
// copied from the parent class and extended to support parsing out the store location.
private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
// Retrieve and parse cookie value.
Cookie cookie = WebUtils.getCookie(request, getCookieName());
Locale locale = null;
TimeZone timeZone = null;
if (cookie != null) {
String value = cookie.getValue();
Map<String, String> params = new HashMap<String, String>();
String[] tokens1 = value.split("::");
for (String token: tokens1){
String[] tokens2 = token.split(":");
params.put(tokens2[0], tokens2[1]);
}
String localeString = params.get("locale");
String timezoneString = params.get("timezone");
String locationString = params.get("location");
if (localeString != null)
{
locale = StringUtils.parseLocaleString(localeString);
}
if (timezoneString != null)
{
timeZone = StringUtils.parseTimeZoneString(timezoneString);
}
if (locationString != null)
{
location = locationService.findForLocaleContext(locationString, false);
}
if (logger.isDebugEnabled()) {
logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +
"'" + (timeZone != null ? " and time zone '" + timeZone.getID() + "'" : ""));
}
}
request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
(locale != null ? locale: determineDefaultLocale(request)));
request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
(timeZone != null ? timeZone : determineDefaultTimeZone(request)));
request.setAttribute(LOCAL_STORE_REQUEST_ATTRIBUTE_NAME,
(location != null ? location : determineDefaultLocalStore(request)));
}
}
/**
* Determine the default time zone for the given request,
* Called if no TimeZone cookie 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
*/
protected Location determineDefaultLocalStore(HttpServletRequest request) {
return getDefaultLocation();
}
@Override
protected Locale getDefaultLocale() {
logger.debug("Getting the default locale");
LocaleContextHolder.getLocaleContext();
return super.getDefaultLocale();
}
public Location getDefaultLocation() {
return defaultLocation;
}
public void setDefaultLocation(Location defaultLocation) {
this.defaultLocation = defaultLocation;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
}
其他主類是擴展LocaleChangeInterceptor
,讓我通過改變本地存儲向任何控制器URL添加參數。
/**
* <p>The custom locale resolver will also handle setting up the customer's local store in the
* locale context.</p>
*
*
*/
@Component
public class StoreLocaleChangeInterceptor extends LocaleChangeInterceptor {
private static Logger logger = LogManager.getLogger(StoreLocaleChangeInterceptor.class.getName());
/**
* Default name of the store locale specification parameter: "store".
*/
public static final String DEFAULT_STORE_PARAM_NAME = "store";
private String storeParamName = DEFAULT_STORE_PARAM_NAME;
@Autowired
private LocationService locationService;
public String getStoreParamName() {
return storeParamName;
}
public void setStoreParamName(String storeParamName) {
this.storeParamName = storeParamName;
}
public LocationService getLocationService() {
return locationService;
}
public void setLocationService(LocationService locationService) {
this.locationService = locationService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
String newLocale = request.getParameter(getParamName());
String newStore = request.getParameter(this.storeParamName);
if (newStore != null || newLocale != null) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver instanceof StoreLocaleResolver)
{
Location location = locationService.findByIdentifier(newStore);
if (location != null) {
((StoreLocaleResolver) localeResolver).setLocation(location);
request.setAttribute(StoreLocaleResolver.LOCAL_STORE_REQUEST_ATTRIBUTE_NAME, location);
}
if (newLocale != null)
{
localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale));
}else
{
Locale currentLocale = localeResolver.resolveLocale(request);
localeResolver.setLocale(request, response, currentLocale);
}
}
}
// Proceed in any case.
return true;
}
}
然後從LocaleContextHolder
我必須向下轉換到上下文類型(這是現在的接口)。
@ModelAttribute("myStore")
protected Location getCurrentStore() {
LocaleContext ctx = LocaleContextHolder.getLocaleContext();
if (StoreAwareLocaleContext.class.isAssignableFrom(ctx.getClass())){
return ((StoreAwareLocaleContext) ctx).getLocation();
}else
{
return null;
}
}