How to validate a locale in java?

China☆狼群 提交于 2019-12-31 17:54:42

问题


I read a file in an application that specifies a language code:

public void setResources(String locale) {

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

}

that must be in the format: <ISO 639 language code>_<ISO 3166 region code> eg. en_UK, en_US etc. Is it possible to validate that the locale string is valid before continuing?


回答1:


I do not know ULocale, but if you mean java.util.Locale, the following code may do:

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;
  }
}

EDIT: added validation




回答2:


isAvailableLocale(Locale locale) 

Is answer to your question.

Example:

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

Avoid using getAvailableLocales() it will return you 155 locales Its time consuming.

If possible please explore more at LocaleUtils class and Locale




回答3:


You can get the available locales like so and enumerate them to see if the locale is valid

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



回答4:


use org.apache.commons.lang.LocaleUtils.toLocale(localeString).

one-liner, other than catching java.lang.IllegalArgumentException.




回答5:


commons lang has a utility method to parse and validate locale strings: LocaleUtils.toLocale(String)

After that, you just have to check whether the variant is empty:

Validate.isTrue( StringUtils.isBlank( locale.getVariant() ) );



回答6:


You could check if the String is contained in the Arrays returned by the getISOCountries() or getISOLanguages() methods of Locale. Its kinda crude but may actually work. You could also extract all available Locales with getAvailableLocales() and search them for display names.




回答7:


There are plenty of answers already but for a fast one-liner:

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

In a method:

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



回答8:


@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());
        }
    }    

}




回答9:


Now I just do:

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

which works fine.




回答10:


I had this problem recently. With the help from Common-lang I came up with this

 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() returns all available locales, but it stores the list in a static variable, so it is iterated only once

LocaleUtils.localeLookupList() takes a locale and creates a list with different granularities.

The code basically validates your locale using a more general version until english is used as fallback.



来源:https://stackoverflow.com/questions/3684747/how-to-validate-a-locale-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!