invalid - ¿Cómo validar un local en java?
java lang illegalargumentexception invalid locale format es_419 jasperserver (10)
Leí un archivo en una aplicación que especifica un código de idioma:
public void setResources(String locale) {
// validate locale
// ULocale lo = new ULocale(locale);
// System.out.println(lo.getDisplayCountry());
}
que debe tener el formato: <ISO 639 language code>_<ISO 3166 region code>
por ejemplo. en_UK, en_US etc. ¿Es posible validar que la cadena de configuración regional es válida antes de continuar?
Ahora solo hago:
ULocale uLocale = new ULocale(locale);
if (uLocale.getCountry() != null && !uLocale.getCountry().isEmpty()) {
...
}
que funciona bien.
No sé ULocale, pero si te refieres a java.util.Locale
, el siguiente código puede hacerlo:
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;
}
}
EDITAR: validación añadida
Puede obtener las configuraciones regionales disponibles así y enumerarlas para ver si la configuración regional es válida
boolean isValidLocale(String value) {
Locale[] locales = Locale.getAvailableLocales();
for (Locale locale : locales) {
if (value.equals(locale.toString())) {
return true;
}
}
return false;
}
Puede verificar si la Cadena está contenida en las Matrices devueltas por los getISOCountries()
o getISOLanguages()
de Locale
. Es un poco crudo pero puede funcionar. También puede extraer todos los Locales
disponibles con getAvailableLocales()
y buscarlos para mostrar nombres.
Tuve este problema recientemente. Con la ayuda de Common-lang se me ocurrió esto
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 () devuelve todos los locales disponibles, pero almacena la lista en una variable estática, por lo que se itera solo una vez
LocaleUtils.localeLookupList () toma una configuración regional y crea una lista con diferentes granularidades.
El código básicamente valida su configuración regional utilizando una versión más general hasta que el inglés se utiliza como alternativa.
Ya hay muchas respuestas, pero para una línea rápida:
Arrays.asList(Locale.getAvailableLocales()).contains(Locale.US)
En un método:
boolean isLocaleAvailable(Locale locale) {
return Arrays.asList(Locale.getAvailableLocales()).contains(locale);
}
use org.apache.commons.lang.LocaleUtils.toLocale(localeString)
.
one-liner, que no sea la captura de java.lang.IllegalArgumentException
.
commons lang tiene un método de utilidad para analizar y validar cadenas de locale: LocaleUtils.toLocale(String)
Después de eso, solo tienes que verificar si la variante está vacía:
Validate.isTrue( StringUtils.isBlank( locale.getVariant() ) );
@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());
}
}
}
isAvailableLocale(Locale locale)
Es respuesta a tu pregunta.
Ejemplo:
String key= "ms-MY";
Locale locale = new Locale.Builder().setLanguageTag(key).build();
if (LocaleUtils.isAvailableLocale(locale))
{
System.out.println("Locale present");
}
Evite usar getAvailableLocales()
, le devolverá 155 locales.
Si es posible, explora más en LocaleUtils class y Locale