web-dev-qa-db-ja.com

Javaでロケールを検証する方法は?

言語コードを指定するアプリケーションでファイルを読み取りました。

public void setResources(String locale) {

    // validate locale
    // ULocale lo = new ULocale(locale);
    // System.out.println(lo.getDisplayCountry());

}

次の形式にする必要があります:<ISO 639 language code>_<ISO 3166 region code>例en_UK、en_USなど。続行する前にロケール文字列が有効であることを検証できますか?

26
u123

今私はちょうどします:

ULocale uLocale = new ULocale(locale);
if (uLocale.getCountry() != null && !uLocale.getCountry().isEmpty()) {
  ...
}

これは正常に動作します。

0
u123

ULocaleはわかりませんが、Java.util.Locale、次のコードで実行できます:

public void setResources(String locale) {
  // validate locale
  Locale lo = parseLocale(locale);
  if (isValid(lo)) {
    System.out.println(lo.getDisplayCountry());
  } else {
    System.out.println("invalid: " + locale);
  }
}

private Locale parseLocale(String locale) {
  String[] parts = locale.split("_");
  switch (parts.length) {
    case 3: return new Locale(parts[0], parts[1], parts[2]);
    case 2: return new Locale(parts[0], parts[1]);
    case 1: return new Locale(parts[0]);
    default: throw new IllegalArgumentException("Invalid locale: " + locale);
  }
}

private boolean isValid(Locale locale) {
  try {
    return locale.getISO3Language() != null && locale.getISO3Country() != null;
  } catch (MissingResourceException e) {
    return false;
  }
}

編集:追加された検証

20
Arne Burmeister
_isAvailableLocale(Locale locale) 
_

あなたの質問への答えです。

例:

_String key= "ms-MY";
Locale locale = new Locale.Builder().setLanguageTag(key).build();
 if (LocaleUtils.isAvailableLocale(locale))
 {
  System.out.println("Locale present");
 }
_

getAvailableLocales()を使用しないでください。これにより、155ロケールが返されます。

可能であれば、さらに詳しく LocaleUtils class および Locale を参照してください。

16
VdeX

そのように利用可能なロケールを取得し、それらを列挙して、ロケールが有効かどうかを確認できます

boolean isValidLocale(String value) {
  Locale[] locales = Locale.getAvailableLocales();
  for (Locale locale : locales) {
    if (value.equals(locale.toString())) {
      return true;
    }
  }
  return false;
}
14
locka

org.Apache.commons.lang.LocaleUtils.toLocale(localeString)を使用します。

キャッチする以外のワンライナーJava.lang.IllegalArgumentException

7
user1876251

commons lang には、ロケール文字列を解析および検証するためのユーティリティメソッドがあります。 LocaleUtils.toLocale(String)

その後、バリアントが空かどうかを確認するだけです。

Validate.isTrue( StringUtils.isBlank( locale.getVariant() ) );
5
Aaron Digulla

すでにたくさんの答えがありますが、速いですone-liner

Arrays.asList(Locale.getAvailableLocales()).contains(Locale.US)

メソッド内:

boolean isLocaleAvailable(Locale locale) {
   return Arrays.asList(Locale.getAvailableLocales()).contains(locale);
}
2
Jared Burrows

LocalegetISOCountries()またはgetISOLanguages()メソッドによって返される配列に文字列が含まれているかどうかを確認できます。やや粗野ですが、実際に動作する可能性があります。 getAvailableLocales()を使用してすべての利用可能なLocalesを抽出し、表示名を検索することもできます。

2
kostja
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RUNTIME)
@Constraint(validatedBy = ValidLocaleValidator.class)
@Documented
public @interface ValidLocale {
    String message() default "{constraints.validlocale}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}   

public class ValidLocaleValidator implements ConstraintValidator<ValidLocale, String> {
    private Set<String> validLocales = new HashSet<String>();

    @Override
    public void initialize(ValidLocale constraintAnnotation) {
        Locale []locales = Locale.getAvailableLocales();
        for (Java.util.Locale l : locales) {
            validLocales.add(l.toString());
        }
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {        
        return validLocales.contains(value);
    }
}

public class ValidLocaleTest {    
public static class MyBeanWithLocale {
    public static final String MSG = "not a locale";

    private String l;
    public MyBeanWithLocale(String l) {
        this.l = l;
    }
    @ValidLocale(message=MSG)
    public String getL() {
        return l;
    }
    public void setL(String l) {
        this.l = l;;
    }
}

    @Test
    public void testLocale() {
        //success
        MyBeanWithLocale b1 = new MyBeanWithLocale("fr_FR");
        Jsr303.validate(b1); //equivalent to Validation.buildDefaultValidatorFactory().getValidator().validate
        //failure
        try {
        MyBeanWithLocale b2 = new MyBeanWithLocale("FRANCE");
        Jsr303.validate(b2);//equivalent to Validation.buildDefaultValidatorFactory().getValidator().validate
        Assert.fail();
        } catch (Exception e) {
        Assert.assertEquals("[" + MyBeanWithLocale.MSG + "]", e.getCause().getMessage());
        }
    }    

}

1
christophe blin

最近この問題が発生しました。 Common-langの助けを借りて、私はこれを思いつきました

 public static Locale getValidLocale(final Locale locale) {

    Set<Locale> locales = LocaleUtils.availableLocaleSet();
    List<Locale> givenLocales = LocaleUtils.localeLookupList(locale, Locale.ENGLISH);
    for (Locale loc : givenLocales) {
        if (locales.contains(loc)) {
            return loc;
        }
    }
    return Locale.ENGLISH;

}

LocaleUtils.availableLocaleSet()は使用可能なすべてのロケールを返しますが、リストを静的変数に格納するため、1回だけ繰り返されます

LocaleUtils.localeLookupList()はロケールを受け取り、さまざまな粒度でリストを作成します。

コードは基本的に、英語がフォールバックとして使用されるまで、より一般的なバージョンを使用してロケールを検証します。

0
santiagozky