2010-09-10 3 views
19

ho letto un file in un'applicazione che specifica un codice di lingua:Come convalidare una locale in java?

public void setResources(String locale) { 

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

} 

che deve essere nel formato: <ISO 639 language code>_<ISO 3166 region code> ad es. en_UK, en_US ecc. È possibile verificare che la stringa locale sia valida prima di continuare?

risposta

0

Ora devo solo fare:

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

che funziona bene.

11

È possibile ottenere le variabili locali come così e enumerarli per vedere se il locale è valida

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

Questo è molto inperformant a causa del gran numero di locali a disposizione! –

+3

Devi solo farlo una volta e metterlo in un set – Rich

+0

È possibile introdurre un elenco ordinato con le impostazioni locali più utilizzate, che viene controllato per primo e aggiunge nuovi locali se confermato, questo dovrebbe ridurre i controlli di tutte le localizzazioni disponibili! – codevour

1

Si potrebbe verificare se la stringa è contenuta nelle Array restituiti dalle getISOCountries() o getISOLanguages() metodi di Locale. È un po 'grezzo ma potrebbe davvero funzionare. Puoi anche estrarre tutti gli Locales disponibili con getAvailableLocales() e cercare i nomi visualizzati.

15

Non so ULocale, ma se si intende java.util.Locale, il seguente codice può fare:

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: convalida aggiunto

+2

Penso che ULocale si riferisca a [questo] (http://icu-project.org/apiref/icu4j/com/ibm/icu/util/ULocale.Type.html). –

+0

Proprio come una FYI. Il delimitatore di default ISO è "-" invece di "_". Vedere https://stackoverflow.com/questions/4904803/en-us-or-en-us-which-one-should-you-use –

+1

@BernieLenz a destra, ma la domanda riguardava il carattere di sottolineatura –

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 ha un metodo di utilità per analizzare e convalidare le stringhe locali: LocaleUtils.toLocale(String)

Dopo di che, basta verificare se la variante è vuota:

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

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

one-liner, diverso dal numero java.lang.IllegalArgumentException.

0

Ho avuto questo problema di recente. Con l'aiuto di Common-lang sono arrivato fino a questo

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() restituisce locali tutti disponibili, ma memorizza l'elenco in una variabile statica, quindi è solo una volta iterato

LocaleUtils .localeLookupList() prende una locale e crea una lista con granularità differenti.

Il codice convalida fondamentalmente le impostazioni internazionali utilizzando una versione più generale finché non viene utilizzato l'inglese come fallback.

1

Ci sono un sacco di risposte già ma per una rapida one-liner:

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

In un metodo:

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

è la risposta alla tua domanda.

Esempio:

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

Evitare di utilizzare getAvailableLocales() lo restituirà locali Il suo tempo.

Se possibile esplorare più a LocaleUtils class e Locale

+1

penso che questa risposta si adatta meglio, grazie mille !!! –

+1

+1 per questo è più semplice di quello di 5 anni. come sopra. Grazie mille. Penso che tu possa usare questo quando vuoi senza preoccuparti della quantità elevata di loop – poring91

+1

ma è org.apache.commons, non voglio includere più libs – user3871754