问题
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