Saheb
Saheb

Reputation: 1492

Spring boot localise every response parameter from RestController

I am trying to localize almost every parameter in the response of each API in my project.

I have figured out that we can do something like this in spring boot:

MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, locale);
return accessor.getMessage(code);

and keep the code versus localized message mapping in messages_en.properties, messages_fr.properties etc.

But for my application I specifically have two requirements:

Is there a way in spring boot to achieve this or are there any libraries available for this?

Upvotes: 1

Views: 1151

Answers (1)

Saheb
Saheb

Reputation: 1492

I have found a solution for this. Instead of using String for fields, I am using a custom class like LocalizedText:

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class LocalizedText {

    private String text;

}

For serialization, I have created a Deserializer LocalizedTextSerailizer, something like this:

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

@Component
 public class LocalizedTextSerializer extends StdSerializer<LocalizedText> {

     private static final long serialVersionUID = 619043384446863988L;

    @Autowired
    I18nUtil messages;

    public LocalizedTextSerializer() {
        super(LocalizedText.class);
    }

    public LocalizedTextSerializer(Class<LocalizedText> t) {
        super(t);
    }

    @Override
    public void serialize(LocalizedText value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(messages.get(value.getText()));
    }

}

I18nUtil:

import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class I18nUtil {

    @Autowired
    private MessageSource messageSource;

    public String get(String code) {
        try {
            MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, Locale.getDefault());
            return accessor.getMessage(code);
        } catch (NoSuchMessageException nsme) {
            log.info("Message not found in localization: " + code);
            return code;
        }
    }
}

This pretty much serves the purpose, I don't have to mess up with the business logic and I can localize any parameter for any response in the application.

Note:

  1. Here I18nUtil, returns the same code if it couldn't find any message in the message.properties.
  2. Default locale is used in I18nUtil, for demonstration.

Upvotes: 1

Related Questions