2015-09-04 19 views
0

我試圖自定義Spring MVC中的LocaleContext來存儲一些附加信息。如何重寫Spring MVC中的LocaleContext

我已經設置了一個自定義localeResolver,迄今爲止工作正常。但我不知道如何自定義語言環境本身。

我寫了這個類:

/** 
* Creates a store aware localisation context 
*/ 
public class SimpleStoreAwareLocaleContext extends SimpleTimeZoneAwareLocaleContext { 

    private Location location; 

    public SimpleStoreAwareLocaleContext(Locale locale, TimeZone timeZone) { 
     super(locale, timeZone); 
    } 

    public Location getLocation() { 
     return location; 
    } 

    public void setLocation(Location location) { 
     this.location = location; 
    } 
} 

但我怎麼得到這個要上LocaleContextHolder的默認LocaleContext? 所以,當我把這個,我想我的場所背景後面的實例.. LocaleContextHolder.getLocaleContext();

有我需要重寫過濾器或東西嗎?

此外,我確信我的理解是正確的 - LocaleContext線程是本地的嗎?所以每個用戶的權利應該不同?

謝謝!

回答

1

好吧,沒有答案,但我主要有這個工作,所以這就是我所做的。我基本上覆制&粘貼大量的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; 
    } 
}