假设我有一个像
这样的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
谢谢。
答案 0 :(得分:59)
facelets中的参数化资源字符串:
如this tutorial中所述,您可以使用h:outputFormat
和f: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;
}
答案 1 :(得分:4)
谢谢Matt Handy :)。我在这里发布我的答案。我也使用了与你的方法相同但添加了描述(注释)的方法。这是我正在使用的代码。这是任何人都可以使用的完整示例:)
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 "<h2>message.test4</h2>"
-->
<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