首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

怎的在架构中合理的设置request中的Lcoale

2012-08-31 
怎样在架构中合理的设置request中的Lcoale相信很多朋友在做J2EE国际化的时候,很可能遇到这个问题。因为requ

怎样在架构中合理的设置request中的Lcoale

相信很多朋友在做J2EE国际化的时候,很可能遇到这个问题。因为request中的Locale是非常重要的,它代表着用户浏览器的设置,同时,很多应用都是在这里读取用户Locale然后进行国际化的。

但是问题就在于,如果我们的应用中很多地方都适应request.getLocale()来获取Locale,但是我们希望使用自己的Locale,比如说是User信息中包含了一个叫Locale的字段。那么我们怎样使用比较方便呢?有人说把Locale存在Session中比较合适。其实这个要视情况而定,我们应用中很多使用request.getLocale(),如果我们放在Session中,那么要去改很多getLocale的方法,很不合算。

如果不需要浏览器的Locale或者说,需要让request的getLocale返回一个Locale是我们设置的User.getLcoale()字段的话,怎么解决这一问题,request没有setLocale()这一方法。

?

    在web.xml中使用filter,给request包装,重写getLocale()方法

    1.使用HttpServletRequestWrapper包装用户的request,在这里可以构造自己想要的方法:

    ?

    [java]?view plaincopyprint?
    1. public?class?LocaleRequestWrapper?extends?HttpServletRequestWrapper{??
    2. ????public?LocaleRequestWrapper(HttpServletRequest?request)?{??
    3. ????????super(request);??
    4. ????}??
    5. ??
    6. ????public?Enumeration?getLocales()?{??
    7. ????????Vector?v?=?new?Vector(1);??
    8. ????????v.add(getLocale());??
    9. ????????return?v.elements();??
    10. ????}??
    11. ??
    12. ????public?Locale?getLocale()?{??
    13. ????????String?localeStr?=?((HttpServletRequest)?getRequest()).getSession().getAttribute("locale").toString();??
    14. ??
    15. ????????Locale?locale?=??new?Locale(localeStr);??
    16. ????????return?locale;??
    17. ????}??
    18. }??

    这里,locale变量被设置在了Session中,在request中提取,并包装了改Locale并向下传递。

    ?

    getLocales()返回的是browser中用户所选的所有languages的一个list。而默认情况下,getLocale()返回的是第一个,对该方法进行重写之后,返回的就是我们放在Session中的locale了。

    2.在I18NFilter 中提取用户的request并包装为LocaleRequestWrapper,向下传递:
    [java]?view plaincopyprint?
    1. public?class?I18NFilter?implements?Filter?{??
    2. ????transient?static?protected?MessageLogger?LOG?=?MessageLogger.getLogger(I18NFilter.class);??
    3. ????@Override??
    4. ????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{??
    5. ??
    6. ????}??
    7. ??
    8. ????@Override??
    9. ????public?void?doFilter(ServletRequest?servletRequest,?ServletResponse?servletResponse,?FilterChain?filterChain)?throws?IOException,?ServletException?{??
    10. ????????if?(servletRequest?instanceof?HttpServletRequest?&&?((HttpServletRequest)?servletRequest).getSession().getAttribute("locale")?!=?null)?{??
    11. ????????????LOG.debug("I18N?filter?processing...");??
    12. ????????????HttpServletRequest?req?=?(HttpServletRequest)servletRequest;??
    13. ????????????LocaleRequestWrapper?wrapper?=?new?LocaleRequestWrapper(req);??
    14. ????????????filterChain.doFilter(wrapper,?servletResponse);??
    15. ????????}?else?{??
    16. ????????????filterChain.doFilter(servletRequest,?servletResponse);??
    17. ????????}??
    18. ????}??
    19. ??
    20. ????@Override??
    21. ????public?void?destroy()?{??
    22. ????}??
    23. }??
    3.在web.xml中配置该filter

    ?

    ?

    [html]?view plaincopyprint?
    1. <filter>??
    2. ????????<filter-name>I18NFilter</filter-name>??
    3. ????????<filter-class>com.rsi.uif.filter.I18NFilter</filter-class>??
    4. ????</filter>??
    5. <filter>??
    别忘了配置filter-mapping:

    ?

    ?

    [html]?view plaincopyprint?
    1. <filter-mapping>??
    2. ????????<filter-name>I18NFilter</filter-name>??
    3. ????????<url-pattern>/route/*</url-pattern>??
    4. </filter-mapping>??

    ?

    这种方案是可行的,但是它有一个明显的问题:当用户第一层登陆进来的时候,由于初次访问server,session中的locale还没有设置(及可能是filter拦截的locale的时候,要访问的页面还没有还是执行,session中没有locale),这时候会出现整个架构使用了浏览器的lcoale。

    ?

    根据我自己的具体应用,做了如下修改:

    ?

      抛开filter,在核心的servlet中的适当位置,对request进行wrap:? ? ? ? 在我们的Framework中,其实使用request.getLocale()来获取locale进行国际化操作的地方主要集中于view上,有一个view的Utility类,用于将request传递给view(JSP\JSF, etc).那么我们找到了合适的位置,在这里,我们不需要去读session中的lcoale,由于在核心servlet中,context是必须的,而且通过context肯定可以获得user的相关信息。比如context.getUser().getLocale().

      ?

      ? ? ? ? 好了,再按照刚才的第一个方案中使用的wrapper,对locale封装。这样user Locale 就进入我们的系统啦,融合默契。

      ?

      [java]?view plaincopyprint?
      1. public?class?LocaleRequestWrapper?extends?HttpServletRequestWrapper{??
      2. ????private?Locale?locale;??
      3. ??
      4. ????public?LocaleRequestWrapper(HttpServletRequest?request,Locale?locale)?{??
      5. ????????super(request);??
      6. ????????this.locale?=?locale;??
      7. ????}??
      8. ??
      9. ????public?Enumeration?getLocales()?{??
      10. ????????Vector?v?=?new?Vector(1);??
      11. ????????v.add(getLocale());??
      12. ????????return?v.elements();??
      13. ????}??
      14. ??
      15. ????public?Locale?getLocale()?{??
      16. ????????return?this.locale;??
      17. ????}??
      18. }??
      这里可以看到,我们新添加了一个字段,叫做locale,在wrap用户的Lcoale的时候要进行初始化:

      ?

      ?

      [java]?view plaincopyprint?
      1. LocaleRequestWrapper?lrw?=?new?LocaleRequestWrapper((HttpServletRequest)request,context.getUserContext().getUser().getLocale());//封装??
      2. dispatcher.forward(lrw,?response);//转发给view??

      ?

      后记--值得改进一下的地方:
      其实不应该把request的getLocales()给简单的重写掉,保留browser的locale在某些情况下是非常有用的。

热点排行