Guida all'internazionalizzazione in Java: traduci i file .properties con l'IA
Configura ResourceBundle, struttura i file .properties, traduci in oltre 40 lingue con l'IA e poi lascia che PTC (Private Translation Cloud) esamini l'app Java in esecuzione tramite schermate o estensione del browser. Alla fine avrai un JAR multilingue pronto per essere rilasciato, con ogni lingua di destinazione verificata prima della release. Per una panoramica del servizio Java autonomo, vedi tradurre le app Java con l'IA.
ResourceBundle carica il file .properties corretto a runtime
Il sistema 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 manca una traduzione, esegue silenziosamente il fallback al file predefinito. Non si rompe nulla, ma le traduzioni mancanti non compaiono nemmeno come errori. 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 è importante.
Configura il tuo bundle di risorse con messages_{locale}.properties
Un bundle di risorse è un set di file .properties che condividono un base name comune. Il base name è 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 usano spesso più bundle di risorse per mantenere tutto organizzato:
src/main/resources/
messages.properties
errors.properties
emails.properties
Java si aspetta uno specifico pattern di denominazione: basename_language.properties o 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. Usare il formato errato significa che ResourceBundle non troverà il file a runtime.
Carica e usa il bundle nel codice, con 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 che rendono 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 tue traduzioni. Questo vale sia che tu traduca manualmente sia con uno strumento IA come PTC.
1. Usa chiavi chiare e descrittive che indicano dove appare la stringa
Le chiavi dovrebbero rendere ovvio dove e come viene usata una stringa. Questo è importante quando gestisci centinaia di stringhe su 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 di .properties:
messages.count = {0,choice,0#no messages|1#one message|1<{0} messages}
Java elabora questo 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 complesse per i plurali.
Per i plurali sensibili alla lingua (one/few/many/other del polacco, le sei forme dell'arabo), usa MessageFormat della libreria 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 di plurali corrette per lingua:
notes.count.zero=No notes yet
notes.count.one={0} note
notes.count.other={0} notes
PTC genera le categorie di plurali corrette per ogni lingua di destinazione. Il polacco ottiene one / few / many / other. Il giapponese ottiene solo other.
4. Esegui l'escape di =, :, # e \ con un backslash
Caratteri come =, :, # e \ hanno un significato speciale nei file .properties:
=o:separa le chiavi dai valori.#o!inizia un commento.\introduce sequenze di escape (come\nper andare a capo).
Esegui l'escape con un backslash 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 si corrompono e le traduzioni diventano illeggibili. Storicamente i file .properties di Java erano ISO-8859-1, richiedendo escape \uXXXX per i caratteri non ASCII. Java 9+ li legge in UTF-8 per impostazione predefinita, quindi controlla la tua versione di runtime prima di fare affidamento sull'UTF-8 puro.
6. Mantieni tutti i testi visibili all'utente fuori dal codice
Se una stringa è visibile agli utenti, appartiene a un file .properties. Le stringhe hardcoded non verranno tradotte. La tua app finirà per mostrare un mix di lingue.
Formatta date, orari, numeri e valute con helper sensibili al locale
Non tutto ciò che richiede localizzazione si trova in un file .properties. Date, orari, numeri e valori di valuta vengono formattati nel codice a runtime, e ottenerli 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"
Valute 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 hardcoded "$", separatori delle migliaia "," o schemi "MM/DD/YYYY".
Collega ResourceBundle a Spring Boot con MessageSource
Spring Boot racchiude ResourceBundle in un bean MessageSource che si integra con le funzionalità i18n del framework. Copre anche i messaggi di convalida, 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/.
Usalo 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'intestazione 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 in spagnolo.
Traduci i file .properties di Java con PTC in 5 passaggi
- Inizia 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 gli schemiChoiceFormat, e legge eventuali commenti#come contesto per il traduttore. - Aggiungi una breve descrizione della tua applicazione Java e del pubblico. PTC la utilizza per tradurre con il tono e la terminologia corretti.
- Scegli le lingue di destinazione e conferma. La prova copre 20.000 parole in 2 lingue, nessuna carta di credito.
- Scarica i file
.propertiestradotti dalla scheda Files. 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) rileva automaticamente le nuove lingue. L'intera configurazione richiede circa 5 minuti.
Automatizza la traduzione di Java a ogni release con Git o l'API di PTC
Tradurre una volta è semplice. Mantenere le traduzioni aggiornate man mano che la tua applicazione si evolve è più difficile. Ogni nuova stringa, ogni aggiornamento dei testi, ogni chiave rimossa deve fluire in ogni lingua. PTC offre due modi per automatizzarlo.
Integrazione Git. Collega il tuo repository GitHub, GitLab o Bitbucket a PTC. PTC monitora il tuo file .properties di origine per rilevare eventuali modifiche. Quando una stringa viene aggiunta o aggiornata, PTC la traduce e restituisce i file aggiornati tramite una merge request.
Integrazione CI/CD. Se preferisci mantenere tutto all'interno del tuo processo di build esistente, l'API di PTC ti consente di caricare il tuo file di origine e recuperare le traduzioni come parte del tuo job 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: Translate with PTC
run: |
cat > .ptc-config.yml <<'EOF'
source_locale: en
files:
- file: src/main/resources/messages.properties
output: src/main/resources/messages_{{lang}}.properties
EOF
curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/main/ptc-cli.sh -o ptc-cli.sh
chmod +x ptc-cli.sh
./ptc-cli.sh --config-file .ptc-config.yml --api-token="${{ secrets.PTC_API_TOKEN }}"
PTC sincronizza le nuove stringhe di origine, traduce solo ciò che è cambiato e apre una PR con messages_es.properties, messages_fr.properties aggiornati, e così via. Per i progetti Maven e Gradle, funziona lo stesso flusso. A PTC non importa quale strumento di build utilizzi. Entrambi gli approcci significano che aggiungere una nuova lingua in seguito è una modifica di configurazione, non un nuovo processo manuale.
Revisione visiva della traduzione della tua app Java tradotta: 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, il risultato visualizzato potrebbe presentare problemi che nessuna revisione a livello di stringa può cogliere:
- Un'etichetta in tedesco che va in overflow su un pulsante Swing.
- Un messaggio di convalida in francese con la forma grammaticale errata.
- Una stringa hardcoded in inglese fuori da
messageSource.getMessage()che viene mostrata non tradotta.
L'AI Visual QA di PTC copre entrambe le varianti di app Java:
- Per Spring Boot o qualsiasi app Java basata sul web: installa l'estensione del browser PTC e registra un percorso guidato delle pagine critiche della tua app. PTC lo riproduce in ogni lingua di destinazione dopo ogni aggiornamento delle traduzioni.
- Per desktop (Swing, JavaFX), server (CLI) o qualsiasi app Java non basata su browser: carica le 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, accezione errata) vengono corretti automaticamente. I problemi nel tuo codice Java (chiamata messageSource.getMessage() mancante, stringa hardcoded, concatenazione di frasi che dovrebbe usare MessageFormat) tornano come prompt pronti da incollare per Cursor o Claude Code.
Il risultato: un JAR multilingue verificato per ogni release. Non solo file property tradotti.
Traduci note di rilascio, README ed email per i clienti
Le tue note di rilascio, i README sul tuo repository Maven interno o su GitHub, le email per i clienti, la documentazione di supporto e le pagine wiki interne si trovano fuori da .properties. Paste to Translate di PTC gestisce questi testi nello stesso progetto. Incolla il testo di origine nel pannello di controllo PTC, scegli le lingue di destinazione e ottieni traduzioni che usano lo stesso glossario e la stessa voce del brand delle tue stringhe in-app.
Traduci dati aziendali, ticket di supporto e contenuti del cliente con l'API di PTC
I dati aziendali, i ticket di supporto, le voci della knowledge base e i contenuti del cliente necessitano di traduzione non appena arrivano. L'API REST di PTC traduce questi contenuti su richiesta con autenticazione tramite token Bearer, usando lo stesso glossario e la stessa voce del brand delle tue traduzioni .properties.
PTC traduce la tua app Java E ne esamina il risultato in esecuzione
Inizia la tua prova di 30 giorni: 20.000 parole in 2 lingue, nessuna 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:
- Traduci le 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 pipeline CI/CD: panoramica del servizio per i team di ingegneria.