2012-02-22 28 views
22

Supongamos que tengo presentar una messages.properties comoCómo leer los mensajes y pasar parámetros al archivo message.properties en JSF 2.0

windowTitle=Accessing Form Elements with JavaScript 
namePrompt=Name: 
passwordPrompt=Password: 
confirmPasswordPrompt=Confirm Password: 

Tengo una entrada para esto en mi faces-config.xml como esto

<faces-config version="2.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"> 

    <application> 
     <resource-bundle> 
      <base-name>pk.mazars.basitMahmood.messages</base-name> 
      <var>msgs</var> 
     </resource-bundle> 
    </application> 

</faces-config> 

En mi página XHTML puedo acceder a ella como esta

<h:panelGrid columns="2" columnClasses="evenColumns, oddColumns"> 
    #{msgs.namePrompt} 
    <h:inputText/> 
    #{msgs.passwordPrompt} 
    <h:inputSecret id="password"/> 
    #{msgs.confirmPasswordPrompt} 
    <h:inputSecret id="passwordConfirm"/> 
</h:panelGrid> 

Pero cómo puedo leer este archivo desde Java. Al igual que, supongamos que tengo que imprimir un mensaje de este tipo, o solicitar al usuario como nombre se debe introducir

System.out.println(msgs.namePrompt + "must be entered") 

¿Cómo puedo leer el valor msgs.namePrompt de mi código java.

También supongamos que tengo una entrada en mi archivo de mensaje como este

sure=Are you sure, you want to delete the <Field>? 
remove=Are you sure you want to remove the<Field> and <Field>? 
close=Are you sure you want to mark the <Field> as Closed? 
created=<Field> is successfully created 
updated=<Field> is successfully updated 

¿Hay alguna técnica que me puede pasar a mi archivo de parámetros messages.properties. Como quiero hacer algo como esto en mi código de Java

System.out.println(msgs.sure("Name")); //<Field> is replace with Name 
System.out.println(msgs.remove("Age", "Gender")); // First Field replace by Age, and second is replace by Gender 

Gracias.

Respuesta

53

cadenas de recursos parametrizado en facelets:

Como se describe en this tutorial, puede utilizar h:outputFormat y f:param para reemplazar sus parametros en una cadena paquete de recursos:

<h:outputFormat value="#{msg['message.param1']}"> 
    <f:param value="param0" /> 
</h:outputFormat> 
<h:outputFormat value="#{msg['message.param2']}"> 
    <f:param value="param0" /> 
    <f:param value="param1" /> 
</h:outputFormat> 

//properties file 
message.param1 = This is "message.param1" - {0} 
message.param2 = This is "message.param2" - {0} and {1} 

En Java se puede acceder a un archivo de propiedades como este:

import java.util.ResourceBundle; 
... 
ResourceBundle rb = ResourceBundle.getBundle("pk.mazars.basitMahmood.messages"); 

Las propiedades parametrizadas se pueden procesar con el javax.text.MessageFormat clase:

MessageFormat.format(rb.getString(key), params); 

Si está trabajando con diferentes escenarios y propiedades parametrizados y no con parámetros, se puede utilizar un método de ayuda a corto como este:

public static String getMessageResourceString(String bundleName, String key, Object params[], Locale locale) { 

     String text; 
     ResourceBundle bundle = ResourceBundle.getBundle(bundleName, locale); 

     try { 
      text = bundle.getString(key); 
     } catch (MissingResourceException e) { 
      text = "?? key " + key + " not found ??"; 
     } 

     if (params != null) { 
      MessageFormat mf = new MessageFormat(text, locale); 
      text = mf.format(params, new StringBuffer(), null).toString(); 
     } 

     return text; 
    } 
4

Gracias Matt práctico :). Aquí estoy publicando mi respuesta. También utilicé un método que es el mismo que el suyo pero con la descripción (comentario) agregada. Aquí está mi código que estoy usando. Este es un ejemplo completo que cualquiera puede utilizar :)

messages.properties presentar

windowTitle=Accessing Form Elements with JavaScript 
namePrompt=Name: 
passwordPrompt=Password: 
confirmPasswordPrompt=Confirm Password: 
message.param1 = This is "message.param1" - {0} 
message.param2 = This is "message.param2" - {0} and {1} 

archivo faces-config.xml

<application> 
    <resource-bundle> 
     <base-name>pk.mazars.basitMahmood.messages</base-name> 
     <var>msgs</var> 
    </resource-bundle> 
</application> 

índice.archivo XHTML

<h:body> 

    <h:form> 

     <h:panelGrid columns="2" columnClasses="evenColumns, oddColumns"> 
      #{msgs.namePrompt} 
      <h:inputText id="name" value="#{readMessages.name}" /> 
      #{msgs.passwordPrompt} 
      <h:inputSecret id="password" value="#{readMessages.password}"/> 
      #{msgs.confirmPasswordPrompt} 
      <h:inputSecret id="passwordConfirm"/> 

     </h:panelGrid> 

     <!--A normal way to access the message. 

       <h:outputText value="{msg.message}" /> 

       //properties file 
       message = This is "message" 

      For a key that has a dot “.” as name, you can’t use the normal way {msg.message.test1}, it 
      will not work. Instead, you should use bracket like {msg['message.test1']}. 

       <h:outputText value="{msg['message.test1']}" /> 

       //properties file 
       message.test1 = This is "message.test1" 

      To display HTML tag in the message, just add the “escape” attribute and set it to false. 

       <h:outputText value="{msg['message.test2']}" /> 
       <h:outputText value="{msg['message.test2']}" escape="false" /> 
       <h:outputText value="{msg['message.test3']}" /> 
       <h:outputText value="{msg['message.test3']}" escape="false" /> 

       //properties file 
       message.test2 = This is "<h2>message.test3</h2>" 
       message.test3 = This is "&lt;h2&gt;message.test4&lt;/h2&gt;" 

     --> 
     <h:outputFormat value="#{msgs['message.param1']}"> 
      <f:param value="param0" /> 
     </h:outputFormat> 

     <h:outputFormat value="#{msgs['message.param2']}"> 
      <f:param value="param0" /> 
      <f:param value="param1" /> 
     </h:outputFormat> 

     <h:commandButton type="button" value="Submit Form" 
          onclick="checkPassword(this.form)"/> 

    </h:form> 

</h:body> 

archivo Java

@Named(value="readMessages") 
@RequestScoped 
public class ReadMessages { 

    private String name; 
    private String password; 

    /** Creates a new instance of ReadMessages */ 
    public ReadMessages() { 

     String[] message1 = {"Basit", "Masood"}; 

     //FacesMessage message = getMessage(
       // "pk.mazars.basitMahmood.messages", "message.param2", new Object[]{new String("arg1")}); 

     String message = getMessage(
       "pk.mazars.basitMahmood.messages", "message.param2", message1); 

     System.out.println(); 

    } // end of constructor 

    public String getName() { 
     return name; 
    } 

    public String getPassword() { 
     return password; 
    } 

    /** 
    * For proper localization, you will want to retrieve error messages from a message bundle. 
    * Doing that involves some busywork with locales and class Loader. 
    * 
    * @param bundleName 
    * @param resourceId 
    * @param params 
    * @return 
    */ 
    public static String getMessage(String bundleName, String resourceId, Object[] params) { 

     /** 
     * Get the current locale. 
     *  FacesContext context = FacesContext.getCurrentInstance(); 
     *  UIViewRoot viewRoot = context.getViewRoot(); 
     *  Locale locale = viewRoot.getLocale(); 
     * 
     */ 
     FacesContext context = FacesContext.getCurrentInstance(); 

     /** 
     * Recall that an application can supply a bundle name in a configuration file, 
     * such as 
     * 
     *  <faces-config> 
     *   <application> 
     *    <message-bundle>pk.mazars.basitMahmood.messages</message-bundle> 
     *   </application> 
     *   ... 
     *  </faces-config> 
     * 
     * The following code snippet retrieves that bundle name: 
     * 
     *  Application app = context.getApplication(); 
     *  String appBundleName = app.getResourceBundle(); 
     */ 
     Application app = context.getApplication(); 
     String appBundle = app.getMessageBundle(); 

     //get Locale 
     Locale locale = getLocale(context); 

     /** 
     * Get the current class loader. You need it to locate the resource bundle 
     * 
     *  ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
     * 
     */ 
     ClassLoader loader = getClassLoader(); 

     /** 
     * Get the resource bundle with the given name, locale and class loader 
     * 
     *  ResourceBundle bundle = ResourceBundle.getBundle(bundleName, locale, loader); 
     * 
     */ 
     String summary = getString(appBundle, bundleName, resourceId, locale, loader, params); 

     if (summary != null) { 

      //summary = "????" + resourceId + "????"; 
      return summary ; 

     } 

     String detail = getString(appBundle, bundleName, resourceId + "detail", locale, loader, params); 
     return detail; 
     //return new FacesMessage(summary, detail); 

    } //end of getMessage() 

    public static String getString(String bundle, String resourceId, Object[] params) { 

     FacesContext context = FacesContext.getCurrentInstance(); 
     Application app = context.getApplication(); 
     String appBundle = app.getMessageBundle(); 
     Locale locale = getLocale(context); 
     ClassLoader loader = getClassLoader(); 
     return getString(appBundle, bundle, resourceId, locale, loader, params); 

    } //end of getString() 

    public static Locale getLocale(FacesContext context) { 

     Locale locale = null; 
     UIViewRoot viewRoot = context.getViewRoot(); 

     if (viewRoot != null) { 

      locale = viewRoot.getLocale(); 

     } //end of if (viewRoot != null) 

     if (locale == null) { 

      locale = Locale.getDefault(); 

     } //end of if (locale == null) 

     return locale; 

    } //end of getLocale() 

    public static ClassLoader getClassLoader() { 

     /** 
     * The Java ClassLoader is a crucial, but often overlooked, component of the Java run-time system. 
     * It is the class responsible for finding and loading class files at run time. 
     * 
     * Among commercially popular programming languages, the Java language distinguishes itself by 
     * running on a Java virtual machine (JVM). This means that compiled programs are expressed in 
     * a special, platform-independent format, rather than in the format of the machine they are 
     * running on. This format differs from traditional executable program formats in a number of 
     * important ways. 
     * 
     * In particular, a Java program, unlike one written in C or C++, isn't a single executable file, 
     * but instead is composed of many individual class files, each of which corresponds to a single 
     * Java class. 
     * 
     * Additionally, these class files are not loaded into memory all at once, but rather are loaded 
     * on demand, as needed by the program. The ClassLoader is the part of the JVM that loads 
     * classes into memory. 
     */ 
     ClassLoader loader = Thread.currentThread().getContextClassLoader(); 

     if (loader == null) { 

      /** 
      * Whether you override findClass or loadClass, getSystemClassLoader gives you direct 
      * access to the system ClassLoader in the form of an actual ClassLoader object (instead 
      * of accessing it implicitly through the findSystemClass call). 
      */ 
      loader = ClassLoader.getSystemClassLoader(); 

     } //end of if (loader == null) 

     return loader; 

    } //end of getClassLoader() 

    public static String getString(String bundle1, String bundle2, String resourceId, 
     Locale locale, ClassLoader loader, Object[] params) { 

     String resource = null; 
     ResourceBundle bundle; 

     if (bundle1 != null) { 

      bundle = ResourceBundle.getBundle(bundle1, locale, loader); 

      if (bundle != null) { 

       try { 

        /** 
        * Get the resource string with the given ID from the bundle. 
        * 
        *  String resource = bundle.getString(resourceId); 
        * 
        */ 
        resource = bundle.getString(resourceId); 

       } catch (MissingResourceException e) { 
       } 

      } //end of if (bundle != null) 

     } //end of if (bundle1 != null) 

     if (resource == null) { 

      bundle = ResourceBundle.getBundle(bundle2, locale, loader); 

      if (bundle != null) { 

       try { 

        /** 
        * Get the resource string with the given ID from the bundle. 
        * 
        *  String resource = bundle.getString(resourceId); 
        * 
        */ 
        resource = bundle.getString(resourceId); 

       } catch (MissingResourceException e) { 
       } 

      } //end of if (bundle != null) 

     } //end of if (resource == null) 

     if (resource == null) { 

      return null; // no match 

     } 

     if (params == null) { 

      return resource; 

     } 

     /** 
     * Finally, you may want some messages to provide detailed information about the 
     * nature of the error. For example, you want to tell the user which character 
     * in the credit card number was objectionable. Message strings can contain 
     * place-holders {0}, {1} and so on - for exanple 
     * 
     *  The card number contains the invalid character {0}. 
     * 
     * The java.text.MessageFormat class can substitute values for the placeholders: 
     * 
     *  Object[] params = ...; 
     *  MessageFormat formatter = new MessageFormat(resource, locale); 
     *  String message = formatter.format(params); 
     * 
     * Here, the params array contains the values that should be substituted. 
     */ 
     MessageFormat formatter = new MessageFormat(resource, locale); 
     return formatter.format(params); 

    } //end of getString() 

} //end of class ReadMessages 
Cuestiones relacionadas