在网上找了一下资料,很多文章推荐使用native2ascii命令。
个人觉得很不方便,因为开发过程中资源文件修改比较频繁,每次都要运行脚本。
用PropertiesEditor插件。
还是很不方便,每个开发客户端都要装,很麻烦。
另外,资源文件,特别是国际化的时候,通常开发人员都喜欢用UTF-8来编码,以方便修改。但调试的时候就会出问题。
解决办法思路:因为struts是使用Classloader.load(InputStream)来加载资源文件的。所以必须继承修改加载资源文件实现类org.apache.struts.util.PropertyMessageResources的loadLocale方法。第二,兼顾资源文件修改的方便性,最好使资源文件xml化。这样只要标准的xml IDE就可以方便修改,从根本上避免的字符集和IDE相关联的问题。而且可以利用JDK1.5的特性:Properties有一个loadFromXML(InputStream)方法可以方便加载。
解决办法:继承和修改资源文件加载相关的两个实现类:
com.yourcompany.struts.util.XMLPropertyMessageResources继承
org.apache.struts.util.PropertyMessageResources
package com.yourcompany.struts.util;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.PropertyMessageResources;
public class XMLPropertyMessageResources extends PropertyMessageResources {
/**
*
*/
private static final long serialVersionUID = 3701712123553100102L;
public XMLPropertyMessageResources(MessageResourcesFactory factory,
String config, boolean returnNull) {
super(factory, config, returnNull);
}
public XMLPropertyMessageResources(MessageResourcesFactory factory,
String config) {
super(factory, config);
}
@Override
protected synchronized void loadLocale(String localeKey) {
if (log.isTraceEnabled()) {
log.trace("loadLocale(" + localeKey + ")");
}
// Have we already attempted to load messages for this locale?
if (locales.get(localeKey) != null) {
return;
}
locales.put(localeKey, localeKey);
// Set up to load the property resource for this locale key, if we can
String name = config.replace('.', '/');
if (localeKey.length() > 0) {
name += ("_" + localeKey);
}
name += ".xml";//此处修改官方代码,便于IDE环境编辑XML
InputStream is = null;
Properties props = new Properties();
// Load the specified property resource
if (log.isTraceEnabled()) {
log.trace(" Loading resource '" + name + "'");
}
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = this.getClass().getClassLoader();
}
is = classLoader.getResourceAsStream(name);
if (is != null) {
try {
props.loadFromXML(is);//此处修改官方代码,加载XML
} catch (IOException e) {
log.error("loadLocale()", e);
} finally {
try {
is.close();
} catch (IOException e) {
log.error("loadLocale()", e);
}
}
if (log.isTraceEnabled()) {
log.trace(" Loading resource completed");
}
} else {
if (log.isWarnEnabled()) {
log.warn(" Resource "+name+" Not Found.");
}
}
// Copy the corresponding values into our cache
if (props.size() < 1) {
return;
}
synchronized (messages) {
Iterator names = props.keySet().iterator();
while (names.hasNext()) {
String key = (String) names.next();
if (log.isTraceEnabled()) {
log.trace(" Saving message key '"
+ messageKey(localeKey, key));
}
messages.put(messageKey(localeKey, key), props.getProperty(key));
}
}
}
}
com.yourcompany.struts.util.XMLMessageResourcesFactory继承
org.apache.struts.util.PropertyMessageResourcesFactory
package com.yourcompany.struts.util;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.PropertyMessageResourcesFactory;
public class XMLMessageResourcesFactory extends PropertyMessageResourcesFactory {
public MessageResources createResources(String config) {
XMLPropertyMessageResources messageResources =
new XMLPropertyMessageResources(this, config, this.returnNull);//此处修改官方代码,使用修改后的资源加载类
String mode = null;
if (getConfig() != null) {
mode = getConfig().getProperty("mode");
}
messageResources.setMode(mode);
return messageResources;
}
}
修改struts-config.xml的此行为:
<message-resources parameter="com.yourcompany.struts.message.ApplicationResources" factory="com.yourcompany.struts.util.XMLMessageResourcesFactory"/>
你的资源文件改为如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Resources for default
</comment>
<entry key="commons.validate.notnull">can't be empty</entry>
<entry key="vo.Packageinfo.packageId">Package ID</entry>
<entry key="vo.Packageinfo.packageAlias">Package Alias</entry>
<entry key="vo.Packageinfo.packageName">Package Name</entry>
<entry key="vo.Packageinfo.packagePrices">Package Prices</entry>
<entry key="vo.Packageinfo.productLimit">Product Limit</entry>
<entry key="vo.Packageinfotbl.description">Description</entry>
</properties>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Resources for zh_CN
</comment>
<entry key="commons.validate.notnull">不能为空</entry>
<entry key="vo.Packageinfo.packageId">套餐ID</entry>
<entry key="vo.Packageinfo.packageAlias">套餐别名</entry>
<entry key="vo.Packageinfo.packageName">套餐名</entry>
<entry key="vo.Packageinfo.packagePrices">套餐价格</entry>
<entry key="vo.Packageinfo.productLimit">允许发布产品数量</entry>
<entry key="vo.Packageinfo.description">描述信息</entry>
</properties>
如果已经有经过native2ascii转换过的资源文件的。可以使用一下代码转换:
Properties props = new Properties();
props.load(new FileInputStream(...));
props.storeToXml(new FileOutputStream(...));
.....
总结:如果是团队开发,修改资源文件的加载类,只需要做一次就可以让团队开发人员省却重复的工作。