仅在本地机器JVM上设置语言环境

时间:2019-06-12 01:33:03

标签: java maven spring-boot locale

出于工作目的,我需要将Java语言环境更改为系统范围内的另一种语言,但是默认情况下似乎没有简便的方法。我为CJK应用程序进行开发,但是更改实际的系统区域设置以匹配它也会重命名主文件夹,这意味着如果我的输入法决定停止工作,则必须重新引导整个系统。

我尝试在

上设置JVM参数(-Duser.language=ja -Duser.locale=JP
  • maven命令行参数(不是我想要的,而是出于绝望而尝试)
  • {$project_dir}/.mvn/jvm.config(不理想)
  • 环境JAVA_ARGS(在/etc/environment下)
  • eclipse / intellij中的maven JVM参数
  • MAVEN_OPTS

但是它们都不起作用。我的智慧到此为止。

为清楚起见,我正在寻找符合以下条件的解决方案:

  • 不是特定于项目的
  • 不需要.mvn之外的项目源代码修改(例如,项目属性文件)
  • 不涉及更改我的实际系统区域设置(en_US
  • 不需要持续维护(例如,不断添加命令行参数)

所以基本上是某种环境变量。

5 个答案:

答案 0 :(得分:1)

您可以在application.propertiesapplication.yaml上包含以下属性:

spring.mvc.locale=pt_BR
spring.mvc.locale-resolver=fixed

将语言环境更改为所需的语言环境。

在配置WebMvcAutoConfiguration时,这些属性用于通过以下方法定义语言环境:

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
    public LocaleResolver localeResolver() {
        if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.mvcProperties.getLocale());
        }
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }

您还可以检查源代码here

答案 1 :(得分:1)

JVM维护自己的当前默认语言环境。 Java规范要求此行为。

通常,JVM实现在JVM启动时检测到主机操作系统默认值,并将其用作自己的默认值。稍后更改主机操作系统的当前默认设置对JVM无效。 Java规范中未指定此行为。

通常可以通过在用于启动JVM的命令行上指定默认语言环境来覆盖该行为。您说您尝试过此操作,但没有解释为什么这不是解决方案。 Java规范中未指定此行为。

外部监控和操作

您可以通过打开一些通信路径来在外部监视和操纵Java中的语言环境。

JMX浮现在脑海。

外部查找

当您的应用启动时,它可能会在外部源中寻找要使用的语言环境的想法,然后将其放在您的应用中。

LDAP服务器就是保存此类值的外部场所。您将使用Java中的JNDI访问服务器并检索值。

致电Locale.setDefault

调用Locale.setDefault将立即影响JVM中所有应用程序中的所有代码。但这并不会持续下去。重新启动应用程序或JVM时必须再次调用。

任何其他代码都可以像您的代码一样调用此代码,从而使其不可靠。我不推荐这种方法。

您可以通过声明静态类变量来对所需的Locale进行硬编码。

static final public Locale LOCALE = Locale.ITALY ;

在应用启动时调用的生命周期代码中,调用Locale.setDefault( SomeClass.LOCALE ) ;

在代码中传递Locale对象

➥我建议始终在您关心的各个地方显式传递Locale作为可选参数。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Locale locale = Locale.CANADA_FRENCH ;  // Pass explicitly your desired/expected `Locale`.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( locale ) ;
String output = today.format( f ) ;
  

狂欢节2019年6月11日

依靠JVM当前的默认语言环境是不可靠的。作为程序员,您依赖于无法控制的外部性。

  • 系统管理员或最终用户可以更改部署中的默认设置。
  • JVM内调用Locale.setDefault的任何应用程序或库的任何线程中的任何代码都会立即影响您的代码。

顺便说一下,时区ZoneId也是如此。最好始终明确地传递您想要的/期望的时区。

此外,如果语言环境或时区至关重要,最好与用户确认。

答案 2 :(得分:1)

您的-Duser.locale=JP JVM参数应为-Duser.country=JP

来自Oracle technical resource on Locale

...在某些Java运行时实现中,应用程序用户可以通过设置user.languageuser.countryuser.variant在命令行上提供此信息来覆盖主机的默认语言环境系统属性。

(不是完整的答案,但我没有足够的声誉来发表评论)

答案 3 :(得分:0)

您可以尝试settig jvm参数,例如(presudocode)

第一种方法,您可以这样做-

java -Duser.country=CA -Duser.language=fr ........

第二种方法是调用方法

Locale.setDefault(Locale)

上述方法会将其设置为jvm明智的语言环境。

按照文档的第三种方式

  

使用显式语言环境

     

在某些计算环境中,应用程序仅使用单个语言环境   在他们的整个生命周期中在其他环境中,应用程序使用   可以更改的全局语言环境。这些环境使您能够   以编程方式更改全局语言环境首选项,该首选项仍保留在   效果,直到您再次明确更改它为止。 Java应用程序   环境是独一无二的,为您提供了使用多种功能的能力   您以任何需要的方式遍及整个应用程序的语言环境。

     

跨国公司的客户遍布全球。这个   意味着他们的客户和员工可能会说不同的话   语言,并对公司及其经营方式有不同的期望   软件应该运行。而且,甚至有可能   通常,让法国员工处理意大利人的销售记录   顾客。在这种情况下,您将需要绝对控制   您的业​​务和用户界面对象用于哪个语言环境   处理和表示数据。您的应用程序可能需要打印   使用意大利日期和货币格式的销售收据,但尚未排序   英国销售员工的客户清单。组合很远   太多了,但Java技术为您提供了灵活性   处理这种复杂性。

     

为了获得最大的灵活性,您必须明确要求   支持您为每个对语言环境敏感的类的目标语言环境   采用。这意味着您必须跟踪多个语言环境的首选项   应用程序方面或将区域设置首选项分配给不同的   用户和客户。

     

如果您已跟踪用户的语言环境偏好设置,则可以创建   通过显式提供区域设置的区域设置敏感类的实例   在构造函数或创建方法中。想象一下一个偏好对象   存储客户的语言环境选择:

Locale userLocale = preferences.getLocale(); 
NumberFormat nf = NumberFormat.getInstance(userLocale);

因此,在这里,您可以在Preference object API中存储您的客户区域设置偏好,然后进行所需的格式化操作等。

您可以做的是设置一个全局语言环境或保留一个默认语言环境。 并在需要时在方法中明确设置所需的“语言环境”。

也请抛出以下链接-

https://www.top-password.com/blog/tag/change-system-locale-windows-command-line/

https://www.oracle.com/technetwork/articles/javase/locale-140624.html#using

答案 4 :(得分:0)

我发现对我有用的唯一方法是将LANG=ja_JP.UTF-8设置为我的IDE上的实际系统环境变量,该变量在启动后会启动(eclipse和intellij都在运行配置下提供了此功能)。但是我真的很不喜欢这种方法。