java - Spring:如何获得 "ACTUAL"/"CURRENT"区域设置,就像它适用于消息一样?

标签 java spring spring-mvc locale 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 -->

对于 TranslationService(即使与问题检查没有直接关系也是:java spring mvc @service method: nullpointerexception | newbie and translation)

这显然使第一个链接中的所有内容都可以正常工作。所以我可以这样做:

<a href="" th:text="#{help}">Help</a>

这是 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);

    }

}

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

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

即使任何页面被调用类似:?lang=it_IT

(确实适用于 messages.properties)

很抱歉,信息可能太多了……但正如我所说,我有点迷失了对谁保留实际语言环境的理解。此外,下一步将从用户配置文件设置区域设置,但如果用户未登录,我需要一个受控的默认值。

那么最后一个问题:我如何获得语言环境?

我想,我遗漏了一些基本要点……而解决方案只是一行。但目前我完成了我的“网络”资源.. ;) 可能是错误的搜索..

另一方面,我提供了一些信息,这样可能会有所帮助 其他人试图实现“gnu gettext”版本。

最佳答案

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

    @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        
    ...
    
    }
    
  2. 最后,在我们的 Controller (或其他地方)中,我们可以获得当前语言环境:

    @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;
    }
    
  3. 然后我们可以在JSP (index.jsp)中显示结果:

    <h1>Current locale = ${currentLocale}</h1>
    

关于java - Spring:如何获得 "ACTUAL"/"CURRENT"区域设置,就像它适用于消息一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29902872/

相关文章:

java - 当服务器抛出 IllegalArgrumentException 等应用程序异常时,预期响应是什么?

spring - 通过 springs `WebClient` 进行api调用但忽略结果的正确方法是什么?

spring - Spring Boot 的 Grails 控制台是什么?

java - 这个 Spring 教程过时了吗?

java - 如何只允许传递特定类型的格式化字符串?

java - 使用递归函数的 n 维 HashMap

java - If else vs switch with stack 逻辑

Java - 如果用户输入无效输入,我将如何返回异常?

spring - 为映射和/或嵌套对象自定义 Spring @RequestParam 反序列化

java - 无法通过 XML 配置 Autowiring Spring session bean