I have a simple class service and it is being injected beautifully on my application. However, I am trying to inject the messages api
to read a few keys on my message files but I am getting the same error:
1) Could not find a suitable constructor in play.i18n.Messages. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. at play.i18n.Messages.class(Messages.java:61)
public class SampleServiceImpl implements SampleService {
private MessagesApi messages;
@Inject
public SampleServiceImpl(MessagesApi messages){
this.messages = messages;
}
}
@ImplementedBy(SampleServiceImpl.class)
public interface SampleService {
}
Is the a way to do that by DI?
I was able to get the value by doing this but it does not look elegant, any options ?
messages.get(new Lang(new Locale("en")), "ticket.form.title")
The reason of such "non-elegancy" is that language (and Messages
) depends on the request.
The Default behavior is that Messages detect current language on the base of cookie, available languages and default language.
Someware under the hood: Messages messages = messagesApi.preferred(request());
- Will select a language from the request, based on the languages available, and fallback to the default language if none of the candidates are available.
Fortunately, there is a special method that you can use to initialize Messages
with the language you want:
import play.i18n.MessagesApi;
import play.i18n.Messages;
import play.i18n.Lang;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
...
Locale englishLocale = new Locale("en");
Lang englishLang = new Lang(englishLocale);
List<Lang> preferredLangs = Arrays.asList(englishLang);
Messages messagesCustom = messagesApi.preferred(preferredLangs);
// the time for elegancy
messages.at("ticket.form.title");
I advise you to create tiny MessagesApiCustom
service, that will do this few strings of code in the initialization time and then will proxy the at
method to the messages.at
, so it will look like:
public class SampleServiceImpl implements SampleService {
private MessagesApiCustom messages;
@Inject
public SampleServiceImpl(MessagesApiCustom messages){
this.messages = messages;
}
private void doSomeStuff(){
Strign message = messages.at("message.key")
}
}
You can go further, and implement language selection based on annotation:
@Named("FR")
private MessagesApiCustom messages;
Of course, if you need the dynamic language selection, then just use the method that is already present in Play.