struts中文问题和jsp是一样的
无非是页面加编码
用filter过滤请求编码
资源文件用native2ascii转码
无非是页面加编码
用filter过滤请求编码
资源文件用native2ascii转码
解决方案 »
- 【 功能已实现】java实现手机发送信息
- 关于Quartz定时的问题,请大有帮忙。
- Tomcat5.0起动时报com.ibm.db2.jcc.c.SqlException错
- java vector iterator 正则匹配中的问题
- ssh整合问题!怎么总找不到action 呢?
- 怎么把2进制转为字符?还有一般文件中的中文用什么编码的,不会是UTF-8吧?比如图片的相机型号和WORD的所有者这些信息?
- 跪求此题解法 !高分相送!!
- 关于tomcat的严重问题,急!在线等!
- 好怪的XPath问题,单独可运行,整合到系统中缺报错,求救!!!
- 那里有struts的学习资料,谢谢
- 帮我看看哪出错了,好多方法都试过了,还是不行...错误信息贴出....谢谢...等待中....
- Struts+Spring+Hibernate分页
-------------------------------------------------------------
由于ApplicationResources.properties文件不支持中文。
前面有文章提到用native2ascii.exe对文件进行编码的转换来解决这个问题,我也提到过修改PropertyMessageResources.java源文件来解决这个问题。
但Struts1.1b2出来以后,我前面提到的那种修改PropertyMessageResources.java的方法不行了,因为在Struts中多个类使用到PropertyMessageResources类。直接进行编码转换将导致其它类无法正常运行。
在1.1b2版本中你依然可以使用native2ascii.exe对文件编码来解决中文问题。
不过在这里提供另一种方法来解决中文问题,让你可以有更多的选择。
这里使用了JDOM来解析XML文件,取得指定的文字信息。
对PropertyMessageResources.java文件的修改如下:package org.apache.struts.util;import org.jdom.Element;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import java.util.List;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;public class PropertyMessageResources extends MessageResources
{
public PropertyMessageResources(MessageResourcesFactory factory,String config)
{
super(factory, config);
log.info("Initializing, config='" + config + "'");
}
public PropertyMessageResources(MessageResourcesFactory factory,String config, boolean returnNull)
{
super(factory, config, returnNull);
log.info("Initializing, config='" + config + "', returnNull=" + returnNull);
}
protected HashMap locales = new HashMap();
protected static final Log log = LogFactory.getLog(PropertyMessageResources.class);
protected HashMap messages = new HashMap();
public String getMessage(Locale locale, String key)
{
if (log.isDebugEnabled())
{
log.debug("getMessage(" + locale + "," + key + ")");
}
String localeKey = localeKey(locale);
String originalKey = messageKey(localeKey, key);
String messageKey = null;
String message = null;
int underscore = 0;
boolean addIt = false; // Add if not found under the original key
// Loop from specific to general Locales looking for this message
while (true)
{
// Load this Locale's messages if we have not done so yet
loadLocale(localeKey);
// Check if we have this key for the current locale key
messageKey = messageKey(localeKey, key);
synchronized (messages)
{
message = (String) messages.get(messageKey);
if (message != null)
{
if (addIt)
messages.put(originalKey, message);
return (message);
}
}
// Strip trailing modifiers to try a more general locale key
addIt = true;
underscore = localeKey.lastIndexOf("_");
if (underscore < 0)
break;
localeKey = localeKey.substring(0, underscore);
}
// Try the default locale if the current locale is different
if (!defaultLocale.equals(locale))
{
localeKey = localeKey(defaultLocale);
messageKey = messageKey(localeKey, key);
loadLocale(localeKey);
synchronized (messages)
{
message = (String) messages.get(messageKey);
if (message != null)
{
if (addIt)
messages.put(originalKey, message);
return (message);
}
}
}
// As a last resort, try the default Locale
localeKey = "";
messageKey = messageKey(localeKey, key);
loadLocale(localeKey);
synchronized (messages)
{
message = (String) messages.get(messageKey);
if (message != null)
{
if (addIt)
messages.put(originalKey, message);
return (message);
}
}
// Return an appropriate error indication
if (returnNull)
return (null);
else
return ("???" + messageKey(locale, key) + "???");
}
// ------------------------------------------------------ Protected Methods
/**
* Load the messages associated with the specified Locale key. For this
* implementation, the <code>config</code> property should contain a fully
* qualified package and resource name, separated by periods, of a series
* of property resources to be loaded from the class loader that created
* this PropertyMessageResources instance. This is exactly the same name
* format you would use when utilizing the
* <code>java.util.PropertyResourceBundle</code> class.
*
* @param localeKey Locale key for the messages to be retrieved
*/
protected void loadLocale(String localeKey) { if (log.isTraceEnabled()) {
log.trace("loadLocale(" + localeKey + ")");
} // Have we already attempted to load messages for this locale?
synchronized (locales) {
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;
String xmlName = name + ".xml";
name += ".properties";
InputStream is = null;
Properties props = new Properties(); // Load the specified property resource
try {
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) {
props.load(is);
is.close();
}
else
{
is = classLoader.getResourceAsStream(xmlName);
if (is != null)
{
org.jdom.input.SAXBuilder builder = new SAXBuilder();
org.jdom.Document doc = builder.build(is);
org.jdom.Element root = doc.getRootElement();
loadFromElement(localeKey,root.getName(),root);
is.close();
}
}
if (log.isTraceEnabled()) {
log.trace(" Loading resource completed");
}
} catch (Throwable t) {
log.error("loadLocale()", t);
if (is != null) {
try {
is.close();
} catch (Throwable u) {
;
}
}
} // Copy the corresponding values into our cache
if (props.size() < 1)
return;
synchronized (messages) {
Enumeration names = props.keys();
while (names.hasMoreElements()) {
String key = (String) names.nextElement();
if (log.isTraceEnabled()) {
log.trace(" Saving message key '" +
messageKey(localeKey, key));
}
messages.put(messageKey(localeKey, key),
props.getProperty(key));
}
} } private void loadFromElement(String localeKey,String key,org.jdom.Element element)
{
if (element.hasChildren())
{
List children = element.getChildren();
for (int i=0;i < children.size();i++)
{
org.jdom.Element child = (org.jdom.Element)children.get(i);
String newKey = key + "." + child.getName();
loadFromElement(localeKey,newKey,child);
}
}
else
{
messages.put(messageKey(localeKey, key),element.getText());
}
}
}编译这个文件你需要到http://www.jdom.org上取得它的bete8版本
并将jdom.jar和xerces.jar加入到你的CLASSPATH里面。
当然Struts.jar也要加到CLASSPATH里面。
编译完以后用这个PropertyMessageResources.class替换掉struts.jar里面的相同文件。
然后重新将struts.jar打包。
大家如果仔细看上面的代码,会发现替换掉这个类以后并不影响到struts的使用,你依然可以使用它默认的.properties文件的方式。
但如果你想试试用.xml文件来作为.properties的替代的话,你需要把你原来的.properties文件移去,并在同样的目录编辑一个新的xml文件。
它的格式象下面的描述一样:
<?xml version="1.0" encoding="GB2312"?>
<letter>
<index>
<title>用户登录</title>
<description>基于Struts1.1.b2架构的教学实例</description>
<copyright>深圳维豪多媒体网络有限公司版权所有 2002</copyright>
<header>请输入用户名和密码登录</header>
<usernameLabel>用户名</usernameLabel>
<passwordLabel>密码</passwordLabel>
<butLogonLabel>登录</butLogonLabel>
<butRegLabel>注册</butRegLabel>
</index>
<error>
<nothisuser>对不起,这个用户不存在</nothisuser>
<passworderror>密码错误</passworderror>
</error>
</letter>
然后你可以通过
<bean:message key="letter.index.tilte"/>
<bean:message key="letter.error.nothisuser"/>
等来引用到xml文件中的内容。大家如果研究过jive的源代码的话一定对这种方式的引用不陌生。
我刚刚完成这个类的修改,并没有做太多的测试,如果有问题的话请尽可能的自己解决,并将问题和修改方法提交到这里来。注意:
1.如果在同一个目录下有ApplicationResources.properties和ApplicationResources.xml的话,将优先使用ApplicationResources.properties文件。
2.在你发布的应用中需要在/WEB-INF/lib下添加jdom.jar和xerces.jar两个包才可以使改类正常运行。
struts提供资源文件完全是为了支持国际化,ApplicationResources.properties根本没有必要出现中文汉字,其他语种的文件都放在ApplicationResources_zh.properties这样的文件中,struts会自动根据浏览器来选择对应的语言。
楼上的不会就不要乱来,居然还需要修改源文件。
楼主,这不是倒分贴吧?