struts1.3 读取资源文件乱码的另一种解决方法

在网上找了一下资料,很多文章推荐使用native2ascii命令。

个人觉得很不方便,因为开发过程中资源文件修改比较频繁,每次都要运行脚本。

用PropertiesEditor插件。

还是很不方便,每个开发客户端都要装,很麻烦。

另外,资源文件,特别是国际化的时候,通常开发人员都喜欢用UTF-8来编码,以方便修改。但调试的时候就会出问题。

[color=blue]解决办法思路[/color]:因为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(...));
.....


总结:如果是团队开发,修改资源文件的加载类,只需要做一次就可以让团队开发人员省却重复的工作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值