Search code examples
javajsf-2eloptional-parametersoptional-arguments

How to call method with optional parameter list in JSF2 / EL 2.2


any idea how (if even possible) to call java method with optional parameters from JSF page? Iam using Java 7,JSF 2.1, EL 2.2 (Glassfish 3.1.2). Thanks in advance...

I got this exception

javax.el.ELException: /example.xhtml: wrong number of arguments
Caused by: java.lang.IllegalArgumentException: wrong number of arguments

Page example

<h:outputText value="#{bean.methodWithParameters('key.en.currentDate', '2012-01-01', '00:00')}"/>
<h:outputText value="#{bean.methodWithParameters('key.en.currentTime', '12:00')}"/>

Bean example

public String methodWithParameters(String key, Object ... params) {
    String langValue = LanguageBean.translate(key);
    return String.format(langValue, params);
}

Properties example

key.en.currentDate=Today is %s and current time is %s.
key.en.currentTime=Current time is %s.

key.en.currentDate=Today is %1$s and current time is %2$s.
key.en.currentTime=Current time is %2$s.

Solution

  • Varargs is not supported in EL.

    As to your concrete functional requirement, you're approaching this totally wrong. You should not reinvent internationalization/localization in JSF, but instead use the JSF-provided facilities. You should be using <resource-bundle> in faces-config.xml or <f:loadBundle> in Facelets file for this. This will load the files by ResourceBundle API and use the MessageFormat API to format the messages. You can then format the strings by <h:outputFormat> with <f:param>.

    E.g. com/example/i18n/text.properties

    key.en.currentDate=Today is {0} and current time is {1}.
    key.en.currentTime=Current time is {0}.
    

    View:

    <f:loadBundle baseName="com.example.i18n.text" var="text" />
    
    <h:outputFormat value="#{text['key.en.currentDate']}">
        <f:param value="2012-01-01" />
        <f:param value="00:00" />
    </h:outputFormat>
    

    Further I'm not sure if that en in the key stands for English or not, but if it indeed stands for the language, then you're making another mistake. The separate languages needs to have each its own properties file like text_en.properties, text_de.properties, etc conform ResourceBundle API rules.

    See also: