Guida all'internazionalizzazione in Java: tradurre i file .properties con l'IA
Configura ResourceBundle, organizza i file .properties, traduci in oltre 40 lingue con l'IA e lascia che PTC (Private Translation Cloud) revisioni l'app Java in esecuzione tramite schermate o l'estensione del browser. Al termine, avrai un JAR multilingue pronto per la produzione, con ogni lingua di destinazione verificata prima del rilascio. Per una panoramica del servizio dedicato ai servizi Java standalone, vedi tradurre app Java con l'IA.
ResourceBundle carica il file .properties corretto a runtime
Il sistema di i18n di Java si basa su due elementi: i file .properties che memorizzano le tue stringhe tradotte e la classe ResourceBundle che carica il file corretto a runtime in base al locale dell'utente.
Quando la tua app è in esecuzione, ResourceBundle controlla il locale dell'utente e carica automaticamente il file corrispondente. Se una traduzione manca, passa silenziosamente al file predefinito. Nulla si interrompe, ma le traduzioni mancanti non vengono segnalate come errori. Come richiamare una stringa nel codice:
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.FRENCH);
String greeting = bundle.getString("welcome.message");
Questo è l'intero meccanismo. Il resto del lavoro di localizzazione avviene nei file .properties stessi, motivo per cui strutturarli correttamente è fondamentale.
Configura il tuo resource bundle con messages_{locale}.properties
Un resource bundle è un insieme di file .properties che condividono un nome di base comune. Il nome di base è la parte del nome del file che precede il suffisso del locale. È ciò che ResourceBundle.getBundle() utilizza per trovare il file corretto a runtime.
src/main/resources/
messages.properties # default (usually English)
messages_fr.properties # French
messages_de.properties # German
messages_es.properties # Spanish
messages_ja.properties # Japanese
messages_zh_CN.properties # Simplified Chinese (note underscore, not hyphen)
Le applicazioni più grandi spesso utilizzano più resource bundle per mantenere l'organizzazione:
src/main/resources/
messages.properties
errors.properties
emails.properties
Java richiede un pattern di denominazione specifico: basename_language.properties, oppure basename_language_COUNTRY.properties per le varianti regionali:
messages_fr.properties # French
messages_fr_CA.properties # French (Canada)
messages_pt_BR.properties # Portuguese (Brazil)
I codici lingua seguono lo standard ISO 639-1. I codici paese seguono lo standard ISO 3166-1. L'uso di un formato errato impedirà a ResourceBundle di trovare il file a runtime.
Carica e usa il bundle nel codice, utilizzando MessageFormat per la sostituzione dei segnaposto:
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.MessageFormat;
public class App {
public static void main(String[] args) {
Locale locale = Locale.of("es");
ResourceBundle messages = ResourceBundle.getBundle("messages", locale);
String welcome = MessageFormat.format(
messages.getString("app.welcome"),
"My App"
);
System.out.println(welcome);
// -> "Bienvenido a My App"
}
}
Per stringhe semplici senza segnaposto, messages.getString("key") è sufficiente.
Sei convenzioni per rendere i tuoi file .properties pronti per la traduzione
Ogni riga è una coppia chiave-valore separata da =. Il modo in cui scrivi il tuo file di origine influisce direttamente sulla qualità delle traduzioni. Questo vale sia che tu traduca manualmente, sia che utilizzi uno strumento di IA come PTC.
1. Usa chiavi chiare e descrittive che indichino dove appare la stringa
Le chiavi dovrebbero rendere ovvio dove e come viene usata una stringa. Questo è importante quando gestisci centinaia di stringhe in più file.
# Incorrect
btn1 = Submit
msg2 = Error
# Correct
form.submit.button = Submit
error.login.invalid_credentials = Invalid username or password
Non cambiare mai una chiave dopo l'inizio della traduzione. Cambiare una chiave rende orfana la traduzione esistente.
2. Usa segnaposto numerati, non la concatenazione di stringhe nel codice
Scrivi la frase completa nel tuo file .properties e usa segnaposto numerati per i contenuti variabili invece di concatenare le stringhe nel codice.
// Incorrect (in code)
"Hello, " + username + "! You have " + count + " new messages."
# Correct (in .properties)
dashboard.greeting = Hello, {0}! You have {1} new messages.
Molte lingue cambiano l'ordine delle parole e le regole di concordanza, quindi dividere le frasi in frammenti rende impossibile una traduzione corretta.
3. Gestisci la pluralizzazione con ChoiceFormat, ICU o chiavi con suffisso
Per la pluralizzazione in Java standard, ChoiceFormat funziona direttamente all'interno dei file .properties:
messages.count = {0,choice,0#no messages|1#one message|1<{0} messages}
Java elabora questo pattern a runtime e restituisce la forma corretta in base al valore passato. ChoiceFormat è semplice ma limitato alla corrispondenza di intervalli numerici. Non gestisce nativamente regole plurali complesse.
Per plurali sensibili alla lingua (come one/few/many/other in polacco o le sei forme dell'arabo), usa MessageFormat di ICU4J:
String pattern = "{0, plural, one {# note} other {# notes}}";
String result = new com.ibm.icu.text.MessageFormat(pattern, locale).format(new Object[]{count});
Oppure codifica i plurali come chiavi separate con suffissi convenzionali, in modo che PTC possa generare le categorie plurali corrette per ogni lingua:
notes.count.zero=No notes yet
notes.count.one={0} note
notes.count.other={0} notes
PTC genera le categorie plurali corrette per ogni lingua di destinazione. Il polacco riceverà one / few / many / other. Il giapponese riceverà solo other.
4. Esegui l'escape di =, :, # e \ con un backslash
Caratteri come =, :, # e \ hanno un significato speciale nei file .properties:
=o:separano le chiavi dai valori.#o!iniziano un commento.\introduce sequenze di escape (come\nper una nuova riga).
Usa il backslash per l'escape dove necessario:
support.link = Visit us at https\://support.example.com
5. Salva i file .properties in UTF-8
Salva sempre i file .properties in UTF-8. Senza di esso, i caratteri non ASCII vengono visualizzati in modo errato e le traduzioni diventano illeggibili. Storicamente i file .properties di Java erano in ISO-8859-1, richiedendo escape \uXXXX per i caratteri non ASCII. Java 9+ li legge come UTF-8 per impostazione predefinita, quindi controlla la tua versione di runtime prima di fare affidamento sul formato UTF-8 grezzo.
6. Tieni tutto il testo rivolto all'utente fuori dal codice
Se una stringa è visibile agli utenti, deve stare in un file .properties. Le stringhe hardcoded non verranno tradotte. La tua app finirà per mostrare un mix di lingue.
Formatta date, ore, numeri e valute con helper sensibili al locale
Non tutto ciò che deve essere localizzato vive in un file .properties. Date, ore, numeri e valori monetari vengono formattati nel codice a runtime, e gestirli correttamente è importante quanto le tue stringhe tradotte.
Date con DateTimeFormatter:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.of("fr"));
System.out.println(today.format(formatter));
// -> "27 mai 2026"
Valuta con NumberFormat:
import java.text.NumberFormat;
import java.util.Currency;
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.of("de", "DE"));
formatter.setCurrency(Currency.getInstance("EUR"));
System.out.println(formatter.format(1999.99));
// -> "1.999,99 €"
Usa sempre formattatori sensibili al locale. Non inserire mai nel codice simboli come "$", separatori delle migliaia come "," o pattern come "MM/DD/YYYY".
Integra ResourceBundle in Spring Boot con MessageSource
Spring Boot racchiude ResourceBundle in un bean MessageSource che si integra con le funzionalità di i18n del framework. Copre anche i messaggi di validazione, i template Thymeleaf e la risoluzione del locale delle richieste web.
Configura in application.properties:
spring.messages.basename=messages
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=false
Posiziona messages.properties, messages_es.properties, ecc. sotto src/main/resources/.
Uso in un controller:
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
@RestController
public class GreetingController {
private final MessageSource messageSource;
public GreetingController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/greeting")
public String greeting(@RequestParam String name) {
return messageSource.getMessage(
"app.greeting",
new Object[]{name},
LocaleContextHolder.getLocale()
);
}
}
Configura il risolutore del locale per leggere dall'header Accept-Language o da un parametro URL:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
registry.addInterceptor(interceptor);
}
}
Ora GET /greeting?name=World&lang=es restituisce la versione spagnola.
Traduci i file .properties di Java con PTC in 5 passaggi
- Avvia un progetto PTC e scegli il tuo locale di origine (Inglese /
messages.properties). - Carica i tuoi file
.propertiese imposta i percorsi di output. PTC analizza la struttura chiave-valore, riconosce i segnapostoMessageFormat({0},{1}) e i patternChoiceFormat, e legge ogni commento#come contesto per il traduttore. - Aggiungi una breve descrizione della tua applicazione Java e del pubblico. PTC la usa per tradurre con il tono e la terminologia corretti.
- Scegli le lingue di destinazione e conferma. La prova gratuita copre 20.000 parole in 2 lingue, senza carta di credito.
- Scarica i file
.propertiestradotti dalla scheda File di risorse. Uno per lingua, con il suffisso corretto (messages_es.properties,messages_fr.properties). Strutturalmente identici all'origine: stesse chiavi, stessi segnaposto, valori tradotti.
Inseriscili in src/main/resources/, ricompila e ResourceBundle.getBundle("messages", locale) rileverà automaticamente le nuove lingue. L'intera configurazione richiede circa 5 minuti.
Automatizza la traduzione Java a ogni rilascio con Git o l'API di PTC
Tradurre una volta è semplice. Mantenere le traduzioni aggiornate man mano che l'applicazione si evolve è più difficile. Ogni nuova stringa, ogni aggiornamento dei testi, ogni chiave rimossa deve fluire verso ogni lingua. PTC offre due modi per automatizzare il processo.
Integrazione Git. Collega il tuo repository GitHub, GitLab o Bitbucket a PTC. PTC monitora il tuo file .properties di origine per rilevare modifiche. Quando una stringa viene aggiunta o aggiornata, PTC la traduce e consegna i file aggiornati tramite una pull request.
Integrazione CI/CD. Se preferisci mantenere tutto all'interno del tuo processo di build esistente, l'API di PTC ti permette di caricare il file di origine e recuperare le traduzioni come parte del tuo job di CI:
# .github/workflows/translate.yml
name: PTC translate
on:
push:
branches: [main]
paths:
- 'src/main/resources/messages.properties'
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trigger PTC translation
run: |
curl -X POST https://api.ptc.wpml.org/v1/projects/${{ secrets.PTC_PROJECT_ID }}/sync \
-H "Authorization: Bearer ${{ secrets.PTC_API_KEY }}"
PTC sincronizza le nuove stringhe di origine, traduce solo ciò che è cambiato e apre una PR con i file messages_es.properties, messages_fr.properties e così via aggiornati. Per i progetti Maven e Gradle, lo stesso flusso funziona correttamente. PTC non dipende dal tuo strumento di build. Entrambi gli approcci significano che aggiungere una nuova lingua in seguito sarà solo una modifica di configurazione, non un nuovo processo manuale.
Revisione visiva della traduzione della tua app Java: rilascia senza QA manuale per lingua
Un file .properties tradotto è necessario ma non sufficiente. Che la tua app Java sia un servizio web Spring Boot che serve HTML, un'app desktop Swing o uno strumento CLI lato server, l'output renderizzato può presentare problemi che nessuna revisione a livello di stringa può rilevare:
- Un'etichetta in tedesco che causa un overflow in un pulsante Swing.
- Un messaggio di validazione in francese con una forma grammaticale errata.
- Una stringa inglese hardcoded fuori da
messageSource.getMessage()che appare non tradotta.
L'AI Visual QA di PTC copre entrambe le tipologie di app Java:
- Per Spring Boot o qualsiasi app Java basata sul web: installa l'estensione del browser di PTC e registra un percorso guidato delle pagine critiche della tua app. PTC lo riproduce in ogni lingua di destinazione dopo ogni aggiornamento della traduzione.
- Per app desktop (Swing, JavaFX), server (CLI) o qualsiasi app Java non basata su browser: carica schermate dell'app Java in esecuzione in ogni lingua di destinazione. L'IA visiva di PTC ispeziona ogni schermata.
I problemi che PTC può correggere nei file .properties (verbo/sostantivo, overflow del layout, significato errato) vengono risolti automaticamente. I problemi nel tuo codice Java (chiamata messageSource.getMessage() mancante, stringa hardcoded, concatenazione di frasi che dovrebbe usare MessageFormat) vengono restituiti come prompt pronti da incollare per Cursor o Claude Code.
Il risultato: un JAR multilingue verificato per ogni rilascio. Non solo file di proprietà tradotti.
Traduci note di rilascio, README ed email per i clienti
Le tue note di rilascio, i file README sul tuo repository Maven interno o su GitHub, le email rivolte ai clienti, la documentazione di supporto e le pagine wiki interne vivono fuori dai file .properties. La funzione Incolla per tradurre di PTC gestisce questi testi nello stesso progetto. Incolla il testo di origine nel pannello di controllo di PTC, scegli le lingue di destinazione e ottieni traduzioni che utilizzano lo stesso glossario e la stessa voce del brand delle stringhe interne all'app.
Traduci dati aziendali, ticket di supporto e contenuti dei clienti con l'API di PTC
I dati aziendali, i ticket di supporto, le voci della knowledge base e i contenuti inviati dai clienti richiedono una traduzione immediata al loro arrivo. La REST API di PTC traduce questi contenuti su richiesta con autenticazione tramite Bearer token, utilizzando lo stesso glossario e la stessa voce del brand delle tue traduzioni dei file .properties.
PTC traduce la tua app Java E revisiona il risultato in esecuzione
Inizia la tua prova gratuita di 30 giorni: 20.000 parole in 2 lingue, senza carta di credito. Carica i tuoi file .properties, ottieni le versioni tradotte in pochi minuti, quindi carica le schermate (o installa l'estensione del browser per Spring Boot) e lascia che PTC verifichi l'app in esecuzione.
Correlati:
- Tradurre app Java con l'IA – panoramica del servizio per i team Java.
- Riferimento API di PTC – endpoint REST per l'integrazione CI.
- Localizzazione software con IA creata per le pipeline CI/CD – panoramica del servizio per i team di ingegneria.