I have an <f:viewParam>
tag on JSF pages that sets GET parameters to the corresponding managed bean after conversion and validation.
If either conversion or validation errors occur, then an appropriate error message is fetched from a resource bundle and displayed on <p:messages>
(may also be <p:growl>
or <h:messages>
).
The application is multilingual. Therefore when a different language is selected, a message should be displayed in that language but it always displays the message according to the default locale en
(for English).
Test.xhtml:
<!DOCTYPE html>
<html lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:view locale="#{localeBean.locale}">
<f:metadata>
<f:viewParam name="id" converter="#{myConverter}" />
</f:metadata>
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:messages />
</h:body>
</f:view>
</html>
The converter:
@FacesConverter("myConverter")
public final class MyConverter implements Converter
{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
ResourceBundle bundle = context.getApplication()
.evaluateExpressionGet(context, "#{messages}", ResourceBundle.class);
String message = bundle.getString("id.conversion.error");
throw new ConverterException(
new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
throw new UnsupportedOperationException(); // Not relevant in this problem.
}
}
Except for the messages from <f:viewParam>
, there is no problem. All other kind of messages are displayed in the language selected by the user.
Is there anything special with <f:viewParam>
?
I can reproduce your problem. Both Mojarra 2.1.25 and MyFaces 2.1.12 expose the same problem. I'm therefore not sure if this is a bug in the JSF impl or an oversight in the JSF spec. So far, it turns out that the viewroot locale is not been set for a GET request before the render response phase is entered. The converter runs during validations phase, far before render response, that explains why it got the default locale instead. I have to investigate it later on and if necessary report an issue to Mojarra.
In the meanwhile, your best bet to solve this problem is to obtain the bundle as follows instead of EL-evaluating the <resource-bundle><var>
:
String basename = "com.example.i18n.message"; // Exactly the same as <resource-bundle><base-name>
Locale locale = context.getApplication().evaluateExpressionGet(context, "#{localeBean.locale}", Locale.class);
ResourceBundle bundle = ResourceBundle.getBundle(basename, locale);
// ...
Update: I've reported issue 3021 as per this problem. I still can't wrap my head around what the spec is saying at this point, but I find the implementation's behavior unintuitive.
Update 2: the Mojarra and MyFaces guys agreed on this. For Mojarra, it's been fixed as per 2.2.5 (no 2.1.x backport yet?) and for MyFaces it's been fixed as per 2.0.19, 2.1.13 and 2.2.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With