Spring:如何获得"ACTUAL"/"CURRENT"语言环境,就像它适用于消息一样?

mar*_*tti 3 java spring locale spring-mvc gettext

我有点困惑,因为我有一个工作系统,但我无法得到实际/当前的语言环境.

工作系统是这样的:

例如:http://www.mkyong.com/spring-mvc/spring-mvc-internationalization-example/

一些messages.properties文件,

一个servlet-context.xml文件:

  <!-- Additional i18n -->
  <bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="en" />
  </bean>

  <bean id="translationService" class="inbiz.webapp.service.TranslationService">
  </bean>
  <alias name="translationService" alias="t" />

  <mvc:interceptors>
    <bean id="localeChangeInterceptor" 
      class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
      <property name="paramName" value="lang" />
    </bean>
  </mvc:interceptors>
  <!-- END: Additional i18n -->
Run Code Online (Sandbox Code Playgroud)

对于TranslationService(即使没有直接关联的问题也检查:java spring mvc @service方法:nullpointerexception | newbie and translation)

这显然使得所有内容都在第一个链接的内部工作.所以我可以这样做:

<a href="" th:text="#{help}">Help</a>
Run Code Online (Sandbox Code Playgroud)

这是thymeleaf(http://www.thymeleaf.org/),但与JSP或JSF基本相同.消息加载了正确的语言环境.

但对于我的TranslationService,我需要像消息包一样获取语言环境.

以下:https://templth.wordpress.com/2010/07/21/configuring-locale-switching-with-spring-mvc-3/,我设置了这个过滤器:

package inbiz.webapp.filters;

import java.io.IOException;

import java.util.Map;
import java.util.Locale;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.LocaleResolver;

import org.springframework.context.i18n.LocaleContextHolder;

import org.springframework.web.servlet.support.RequestContextUtils;

import org.springframework.web.filter.OncePerRequestFilter;

public class LocaleConfigurerFilter extends OncePerRequestFilter {

    private LocaleResolver localeResolver;


    protected void initFilterBean() throws ServletException {

    Locale locale;

        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        Map resolvers = wac.getBeansOfType(LocaleResolver.class);
        if (resolvers.size()==1) {
            localeResolver = (LocaleResolver) resolvers.values().iterator().next();
        }

    locale = LocaleContextHolder.getLocale();
    System.out.println("DEBUG FILTER LOCALE LCH - INIT: "+locale);

    }


    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
    throws IOException, ServletException {

    Locale locale;

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());

        Map resolvers = wac.getBeansOfType(LocaleResolver.class);
        if (resolvers.size()==1) {
            localeResolver = (LocaleResolver) resolvers.values().iterator().next();
        }
        if (localeResolver!=null) {
            locale = localeResolver.resolveLocale(req);
        System.out.println("DEBUG FILTER LOCALE LRS: "+locale);
            LocaleContextHolder.setLocale(locale);
        }

    locale = LocaleContextHolder.getLocale();
    System.out.println("DEBUG FILTER LOCALE LCH: "+locale);
    locale = RequestContextUtils.getLocale((HttpServletRequest) req);
    System.out.println("DEBUG FILTER LOCALE RCU: "+locale);
    LocaleContextHolder.setLocale(locale);

    chain.doFilter(req, res);

    }

}
Run Code Online (Sandbox Code Playgroud)

调用过滤器,但输出只是:

DEBUG FILTER LOCALE LCH - INIT: en_US
DEBUG FILTER LOCALE LCH: en_US
DEBUG FILTER LOCALE RCU: en_US
DEBUG FILTER LOCALE LCH: en_US
DEBUG FILTER LOCALE RCU: en_US
DEBUG FILTER LOCALE LCH: en_US
DEBUG FILTER LOCALE RCU: en_US
Run Code Online (Sandbox Code Playgroud)

即使用以下内容调用任何页面:?lang = it_IT

(确实适用于messages.properties)

我很抱歉这可能是太多的信息.​​..但正如我所说,我在理解谁保持实际的语言环境方面有点迷失.此外,下一步将是从用户配置文件设置区域设置,但如果用户未登录,则需要受控制的默认值.

所以最后一个问题是:我如何获得语言环境?

我想,我想念一些基本要点......解决方案只是一条线.但目前我完成了我的"网络"资源..;)也许是一个错误的搜索..

另一方面,我提供了一些信息,以便它可以帮助其他人尝试实现"gnu gettext"版本.

Lor*_*ton 7

  1. 首先,让我们考虑如何LocaleResolver在Spring上下文中注册(注意,设置默认语言环境):

    @Configuration
    @EnableWebMvc
    @ComponentScan(value = "com.locales.package")
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Bean(name = "localeResolver")
        public LocaleResolver getLocaleResolver(){
            CookieLocaleResolver localeResolver = new CookieLocaleResolver();
            localeResolver.setDefaultLocale(Locale.ENGLISH);
            return localeResolver;
        }
    
    ...
    // Other beans        
    ...
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 最后在我们的控制器(或其他地方),我们可以获得当前的区域设置:

    @Autowired
    private LocaleResolver localeResolver;
    
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView resolveLocale(ModelMap model, HttpServletRequest request) {
        Locale locale = localeResolver.resolveLocale(request);
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("currentLocale", locale.getDisplayLanguage());
    
        return modelAndView;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后我们可以在JSP(index.jsp)显示结果:

    <h1>Current locale = ${currentLocale}</h1>
    
    Run Code Online (Sandbox Code Playgroud)


mar*_*tti 0

我将其作为答案发布:

在我的 bean id="localeResolver" 中,我将 SessionLocaleResolver 定义为“解析器”。

所以现在一个新的代码是这样的:

protected void initFilterBean() throws ServletException {

try {
    sessionLocaleResolver = new SessionLocaleResolver();
    //System.out.println("DEBUG FILTER LOCALE SLR - INIT: Got SLR ");
} catch (Exception e) {
    //System.out.println("DEBUG FILTER LOCALE SLR - INIT: CANNOT START ");
    logger.error("Could not intialize SessionLocaleResolver.");
}

}


@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws IOException, ServletException {

Locale newLocale;
    if (sessionLocaleResolver!=null) {
    newLocale = sessionLocaleResolver.resolveLocale(req);
    if (newLocale!=null){
    System.out.println("DEBUG FILTER LOCALE OLD: "+locale);
    System.out.println("DEBUG FILTER LOCALE NEW: "+newLocale);
    if (locale != newLocale){
        System.out.println("DEBUG FILTER LOCALE CALL: "+locale);
        if (locale != null){
        //t.updateLocale(newLocale);
        }
    }
    locale = newLocale;
    //System.out.println("DEBUG FILTER LOCALE SLR: "+locale);
    logger.debug("DEBUG FILTER LOCALE: In filter session: Locale {}.", locale);
    LocaleContextHolder.setLocale(locale);
    } else {
    //System.out.println("DEBUG FILTER LOCALE SLR - FILTER: NO RESOLVER");
    logger.error("In session: Could not resolve locale SessionLocaleResolver.");
    }
} else {
    //System.out.println("DEBUG FILTER LOCALE SLR - FILTER: WAS NULL");
    logger.error("In session: Could not get SessionLocaleResolver.");
}

chain.doFilter(req, res);

}
Run Code Online (Sandbox Code Playgroud)

我实际上可以使用:

sessionLocaleResolver.resolveLocale(req);

它将解析为正确的区域设置。