2010-09-10 3 views
19

Je lis un fichier dans une application qui spécifie un code de langue:Comment valider une locale dans java?

public void setResources(String locale) { 

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

} 

qui doit être au format: <ISO 639 language code>_<ISO 3166 region code> par exemple. en_UK, en_US etc. Est-il possible de valider que la chaîne locale est valide avant de continuer?

Répondre

0

Maintenant, je fais juste:

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

qui fonctionne bien.

11

Vous pouvez obtenir les paramètres régionaux disponibles comme ainsi et les énumérer pour voir si les paramètres régionaux est valide

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

Ceci est très inperformant en raison du grand nombre de lieux disponibles! –

+3

Vous ne devez le faire qu'une seule fois et le mettre dans un ensemble – Rich

+0

Vous pouvez introduire une liste triée avec les locales les plus utilisées, qui est vérifiée en premier et ajoute de nouveaux locaux si elle est confirmée, cela devrait réduire les vérifications de tous les paramètres locaux disponibles! – codevour

1

Vous pouvez vérifier si la chaîne est contenue dans les tableaux retournés par les méthodes de getISOCountries() ou getISOLanguages()Locale. C'est un peu brut, mais peut effectivement fonctionner. Vous pouvez également extraire tous les Locales disponibles avec getAvailableLocales() et leur rechercher des noms d'affichage.

15

Je ne sais pas ULocale, mais si vous voulez dire java.util.Locale, le code suivant peut faire:

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: validation ajouté

+2

Je pense que ULocale se réfère à [this] (http://icu-project.org/apiref/icu4j/com/ibm/icu/util/ULocale.Type.html). –

+0

Juste comme un FYI. Le délimiteur ISO par défaut est "-" au lieu de "_". Voir https://stackoverflow.com/questions/4904803/en-us-or-en-us-which-one-should-you-use –

+1

@BernieLenz droite, mais la question était sur le trait de soulignement –

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

}

5

commons lang a une méthode utilitaire pour analyser et valider les chaînes locale: LocaleUtils.toLocale(String)

Après cela, il vous suffit de vérifier si la variante est vide:

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

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

un seul, autre que l'attrape java.lang.IllegalArgumentException.

0

J'ai eu ce problème récemment. Avec l'aide de Common-lang je suis venu avec cette

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() retourne tous les lieux disponibles, mais il stocke la liste dans une variable statique, il est donc itérer une seule fois

LocaleUtils .localeLookupList() prend une locale et crée une liste avec des granularités différentes.

Le code valide fondamentalement vos paramètres régionaux en utilisant une version plus générale jusqu'à ce que l'anglais soit utilisé comme solution de secours.

1

Il y a beaucoup de réponses déjà, mais pour un one-liner rapide:

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

Dans une méthode:

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

est la réponse à votre question.

Exemple:

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

Évitez d'utiliser getAvailableLocales() il vous revenir Paramètres régionaux Son temps.

Si possible s'il vous plaît explorer plus à LocaleUtils class et Locale

+1

Je pense que cette réponse convient le mieux, merci beaucoup !!! –

+1

+1 pour celui-ci est plus simple que 5 y.o. aswer ci-dessus. Merci beaucoup. Je pense que vous pouvez l'utiliser quand vous le voulez sans vous soucier de l'ammount élevé de la boucle – poring91

+1

mais c'est org.apache.commons, je ne veux pas inclure plus de libs – user3871754