Skip to main content

Overview

The Validator library supports internationalization (i18n) through the Messages interface. You can switch between built-in languages (English and Spanish) or create custom message implementations for any language.

Built-in Languages

The library includes two built-in message implementations:
  • MessagesEn - English messages (default)
  • MessagesEs - Spanish messages

Changing the Default Language

Use the static Validator.setMessages() method to change the language globally:

Switch to Spanish

import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.messages.MessagesEs;

public class Application {

    public static void main(String[] args) {
        // Set Spanish as the default language
        Validator.setMessages(new MessagesEs());
        
        // All validators created after this will use Spanish messages
        Validator validator = new Validator.Builder()
            .required()  // "Requerido"
            .email()     // "Correo electrónico inválido"
            .build();
    }

}

Switch to English

import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.messages.MessagesEn;

public class Application {

    public static void main(String[] args) {
        // Explicitly set English (already the default)
        Validator.setMessages(new MessagesEn());
    }

}
The setMessages() method affects all validators in your application. Call it early in your application’s initialization, typically in the main() method or application startup.

Message Translations Reference

Here are some commonly used validation messages in both languages:
RuleEnglish (MessagesEn)Spanish (MessagesEs)
requiredRequiredRequerido
emailEmail invalidCorreo electrónico inválido
minLength%d or more characters are requiredSe requiere %d o más caracteres
maxLength%d or less characters requiredSe requiere %d o menos caracteres
compareNot matchNo coinciden
numberIt is not a numberNo es un número
onlyNumbersOnly numbersSolo números
onlyLettersOnly lettersSolo letras
nameInvalid personal nameNombre personal inválido
RuleEnglishSpanish
compareNot matchNo coinciden
dateThe date does not match the format %sLa fecha no coincide con el formato %s
emailEmail invalidCorreo electrónico inválido
expirationDateExpired dateFecha expirada
httpLinkInvalid http linkEnlace http inválido
httpsLinkInvalid https linkEnlace https inválido
ipInvalid IPIP inválida
ipv4Invalid IPv4IPv4 inválida
ipv6Invalid IPv6IPv6 inválida
lengthIt requires %d charactersSe requiere %d caracteres
linkInvalid linkEnlace inválido
maxLength%d or less characters requiredSe requiere %d o menos caracteres
maxValueThe value cannot be greater than %1$.2fEl valor no puede ser mayor a %1$.2f
minAgeYou must be at least %d years oldSe debe tener al menos %d años
minLength%d or more characters are requiredSe requiere %d o más caracteres
minValueThe value cannot be less than %1$.2fEl valor no puede ser menor a %1$.2f
mustContainMinAt least %d of the following characters are required: %sSe requiere al menos %d de los siguientes caracteres: %s
mustContainOneAt least one of the following characters is required: %sSe requiere al menos uno de los siguientes caracteres: %s
nameInvalid personal nameNombre personal inválido
notContainThe following characters aren’t admitted %sNo se admiten los siguientes caracteres %s
numberIt is not a numberNo es un número
numberPatternDoes not match pattern %sNo coincide con el patrón %s
onlyAlphanumericJust alphanumeric charactersSolo caracteres alfanuméricos
onlyLettersOnly lettersSolo letras
onlyNumbersOnly numbersSolo números
rangeLengthThe text must contain between %d to %d charactersEl texto debe contener entre %d a %d caracteres
rangeValueThe value must be between %1.2fand.2f and %1.2fEl valor debe estar entre %1.2fy.2f y %1.2f
regExpThe value does not match the regular expression %sEl valor no coincide con la expresión regular %s
requiredRequiredRequerido
shouldOnlyContainThey are just admitted the following characters %sSolo se admiten los siguientes caracteres %s
timeTime invalidHora inválida
time12Invalid 12 hour formatFormato 12 horas inválido
time24Invalid 24 hour formatFormato 24 horas inválido
wwwLinkInvalid www linkEnlace www inválido

Creating Custom Messages

You can create custom message implementations for any language or to customize specific messages.

Implementing the Messages Interface

1

Create a class implementing Messages

MessagesFr.java
package com.myapp.validation;

import io.github.ApamateSoft.validator.messages.Messages;

public class MessagesFr implements Messages {
    
    @Override
    public String getRequiredMessage() {
        return "Obligatoire";
    }
    
    @Override
    public String getEmailMessage() {
        return "Email invalide";
    }
    
    @Override
    public String getMinLengthMessage() {
        return "%d caractères ou plus sont requis";
    }
    
    // Implement all other methods from the Messages interface...
}
2

Apply your custom messages

import com.myapp.validation.MessagesFr;
import io.github.ApamateSoft.validator.Validator;

public class Application {
    public static void main(String[] args) {
        Validator.setMessages(new MessagesFr());
    }
}

Messages Interface Reference

The Messages interface defines methods for all validation rules. Each method returns a String message:
public interface Messages {
    String getCompareMessage();
    String getDateMessage();
    String getEmailMessage();
    String getExpirationDateMessage();
    String getHttpLinkMessage();
    String getHttpsLinkMessage();
    String getIpMessage();
    String getIpv4Message();
    String getIpv6Message();
    String getLengthMessage();
    String getLinkMessage();
    String getMaxLengthMessage();
    String getMaxValueMessage();
    String getMinAgeMessage();
    String getMinLengthMessage();
    String getMinValueMessage();
    String getMustContainMinMessage();
    String getMustContainOneMessage();
    String getNameMessage();
    String getNotContainMessage();
    String getNumberMessage();
    String getNumberPatternMessage();
    String getOnlyAlphanumericMessage();
    String getOnlyLettersMessage();
    String getOnlyNumbersMessage();
    String getRangeLengthMessage();
    String getRangeValueMessage();
    String getRegExpMessage();
    String getRequiredMessage();
    String getShouldOnlyContainMessage();
    String getTimeMessage();
    String getTime12Message();
    String getTime24Message();
    String getWwwLinkMessage();
}
Many message methods return format strings with placeholders like %d or %s. These are replaced with actual values when the validator creates error messages. For example, getMinLengthMessage() returns "%d or more characters are required", and the validator replaces %d with the actual minimum length.

Per-Validator Custom Messages

You can override default messages for individual validators without changing the global language:
import io.github.ApamateSoft.validator.Validator;

Validator customValidator = new Validator.Builder()
    .required("This field cannot be empty")  // Custom message
    .minLength(8, "Please enter at least 8 characters")  // Custom message
    .email("Please provide a valid email address")  // Custom message
    .build();
This approach is useful when you want:
  • More specific error messages for certain fields
  • To mix languages in the same application
  • User-friendly messages that differ from the default

Custom Messages with Annotations

Annotations also support custom messages:
import io.github.ApamateSoft.validator.annotations.*;

public class User {

    @Required(message = "Le nom d'utilisateur est obligatoire")
    @MinLength(min = 3, message = "Au moins 3 caractères requis")
    private String username;
    
    @Required(message = "L'email est obligatoire")
    @Email(message = "Format d'email invalide")
    private String email;

}

Runtime Language Switching

You can change languages at runtime based on user preferences:
import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.messages.MessagesEn;
import io.github.ApamateSoft.validator.messages.MessagesEs;

public class LanguageManager {
    
    public void setLanguage(String languageCode) {
        switch (languageCode) {
            case "es":
                Validator.setMessages(new MessagesEs());
                break;
            case "en":
            default:
                Validator.setMessages(new MessagesEn());
                break;
        }
    }
    
}
Changing messages at runtime affects all new validators created after the change. Existing validator instances will continue using the messages they were created with. If you need to update existing validators, create new instances after changing the messages.

Extending Built-in Messages

You can extend existing message classes to customize only specific messages:
import io.github.ApamateSoft.validator.messages.MessagesEn;

public class CustomMessagesEn extends MessagesEn {
    
    @Override
    public String getRequiredMessage() {
        return "This field is required. Please provide a value.";
    }
    
    @Override
    public String getEmailMessage() {
        return "Please enter a valid email address (e.g., [email protected]).";
    }
    
    // All other messages inherit from MessagesEn
}
Then use your custom implementation:
Validator.setMessages(new CustomMessagesEn());

Best Practices

Set language early

Call Validator.setMessages() during application initialization before creating any validators.

Use custom messages for clarity

Override default messages when you need more specific, user-friendly error text.

Extend, don't replace

Extend existing message classes to customize only what you need.

Test in all languages

Ensure your validation logic works correctly with all supported languages.

Next Steps

Error Handling

Learn how to handle validation errors effectively

Form Validation

Apply localization to complete form validation

Build docs developers (and LLMs) love