【问题标题】:How to read messages and pass parameters to message.properties file in JSF 2.0如何在 JSF 2.0 中读取消息并将参数传递给 message.properties 文件
【发布时间】:2012-03-12 12:52:23
【问题描述】:

假设我有一个类似的 messages.properties 文件

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

我的 faces-config.xml 中有一个这样的条目

<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>

在我的 xhtml 页面上,我可以像这样访问它

<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>

但是我怎样才能从 Java 中读取这个文件。比如,假设我必须打印这样的消息,或者提示用户必须输入姓名

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

如何从我的 java 代码中读取 msgs.namePrompt 值。

还假设我的消息文件中有这样的条目

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

是否有任何技术可以将参数传递给我的 messages.properties 文件。就像我想在我的 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

谢谢。

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    facelets 中的参数化资源字符串:

    this tutorial 中所述,您可以使用h:outputFormatf:param 替换资源包字符串中的参数:

    <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}
    

    在 Java 中,您可以像这样访问属性文件:

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

    可以使用javax.text.MessageFormat 类处理参数化属性:

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

    如果您使用不同的语言环境以及参数化和非参数化的属性,您可以使用这样的简短帮助方法:

    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;
        }
    

    【讨论】:

      【解决方案2】:

      感谢马特·汉迪:)。我在这里发布我的答案。我还使用了一种与您的方法相同但添加了描述(评论)的方法。这是我正在使用的代码。这是任何人都可以使用的完整示例:)

      messages.properties 文件

      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}
      

      faces-config.xml 文件

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

      index.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>
      

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-03
        • 2011-08-04
        • 2014-02-09
        • 1970-01-01
        • 2015-04-29
        • 2011-04-26
        • 1970-01-01
        相关资源
        最近更新 更多