你好,欢迎访问我的博客!登录
当前位置:首页 - openfire - 正文 求知成瘾,却无作品!

openfire控制台乱码问题

2019-08-27openfire攻城狮5002°c
A+ A-


最近在折腾openfire,源码在IDEA里面跑起来后,发现IDEA控制台输出中文是乱码,而且访问管理端地址,语言不管选中文还是英文,菜单部分依然还是有乱码存在,找了好久,总算是解决了问题,通过百度查到的,千篇一律的都说啥国际化文件里面少了部分属性,所以导致乱码,我也跟着尝试了,并没有什么用,最后还是自己调试源码解决了问题。

openfire版本:4.4.0

选择的语言是中文。

下面是乱码的控制台界面。(其实已经修复了中间部分的乱码了,中间部分已经是正常显示了)

104.png


其实这种乱码,主要有两个地方,首先第一个地方是JSTL的jar包,jar包的名字是 taglibs-standard-impl-1.2.5.jar 出问题的类是org.apache.taglibs.standard.tag.common.fmt.MessageSupport.java  

这个类主要影响的是所有写了<fmt:message key="index.title.info"/> 标签的JSP页面,上面我标记出来的类就是负责将该标签中的"index.title.info"通过i18n国际化文件转换为对应语言的字符串。

在转换的过程中我不知道为啥它取到的是乱码,但是我在它下面添加了几行代码,重新给字符串编码,就解决了这个问题。

主要该的是这个类中的doEndTag()方法中的几行代码,整个类我就不贴出来了,这个方法的代码如下:

@Override
    public int doEndTag() throws JspException {

        String key = null;
        LocalizationContext locCtxt = null;

        // determine the message key by...
        if (keySpecified) {
            // ... reading 'key' attribute
            key = keyAttrValue;
        } else {
            // ... retrieving and trimming our body
            if (bodyContent != null && bodyContent.getString() != null) {
                key = bodyContent.getString().trim();
            }
        }

        if ((key == null) || key.equals("")) {
            try {
                pageContext.getOut().print("??????");
            } catch (IOException ioe) {
                throw new JspTagException(ioe.toString(), ioe);
            }
            return EVAL_PAGE;
        }

        String prefix = null;
        if (!bundleSpecified) {
            Tag t = findAncestorWithClass(this, BundleSupport.class);
            if (t != null) {
                // use resource bundle from parent <bundle> tag
                BundleSupport parent = (BundleSupport) t;
                locCtxt = parent.getLocalizationContext();
                prefix = parent.getPrefix();
            } else {
                locCtxt = BundleSupport.getLocalizationContext(pageContext);
            }
        } else {
            // localization context taken from 'bundle' attribute
            locCtxt = bundleAttrValue;
            if (locCtxt.getLocale() != null) {
                SetLocaleSupport.setResponseLocale(pageContext,
                    locCtxt.getLocale());
            }
        }
        //注意这里,这里就是我改过的地方---start
        //String message = UNDEFINED_KEY + key + UNDEFINED_KEY;
        String message = key;
        if (locCtxt != null) {
            ResourceBundle bundle = locCtxt.getResourceBundle();
            if (bundle != null) {
                try {
                    // prepend 'prefix' attribute from parent bundle
                    if (prefix != null) {
                        key = prefix + key;
                    }
                    //message = bundle.getString(key);
                    try{
                        message = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
                    }catch (Exception e){

                     }finally {
                        try{
                            message = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
                        }catch (Exception e){

                        }
                    }
                    //这里是结束地方 ----end
                    // Perform parametric replacement if required
                    if (!params.isEmpty()) {
                        Object[] messageArgs = params.toArray();
                        MessageFormat formatter = new MessageFormat(""); // empty pattern, default Locale
                        if (locCtxt.getLocale() != null) {
                            formatter.setLocale(locCtxt.getLocale());
                        } else {
                            // For consistency with the <fmt:formatXXX> actions,
                            // we try to get a locale that matches the user's preferences
                            // as well as the locales supported by 'date' and 'number'.
                            //System.out.println("LOCALE-LESS LOCCTXT: GETTING FORMATTING LOCALE");
                            Locale locale = SetLocaleSupport.getFormattingLocale(pageContext);
                            //System.out.println("LOCALE: " + locale);
                            if (locale != null) {
                                formatter.setLocale(locale);
                            }
                        }
                        formatter.applyPattern(message);
                        message = formatter.format(messageArgs);
                    }
                } catch (MissingResourceException mre) {
                    message = UNDEFINED_KEY + key + UNDEFINED_KEY;
                }
            }
        }

        if (var != null) {
            pageContext.setAttribute(var, message, scope);
        } else {
            try {
                pageContext.getOut().print(message);
            } catch (IOException ioe) {
                throw new JspTagException(ioe.toString(), ioe);
            }
        }

        return EVAL_PAGE;
    }


因为这个是该的是jar包的源码,因此在编译后要覆盖Openfire-4.4.0\distribution\target\distribution-base\lib 这个路径下的taglibs-standard-impl-1.2.5.jar这个包中的类,下图是我的路径,根据自己项目的路径参考一下

405.png


替换完成后,至少登录页面已经是中文了。

但是登陆成功后还是看到了文章一开始的那个截图页面,菜单啥的都还是乱码,所以我又继续深入跟踪了一下,发现openfire的管理端用的是dwr技术,因此花了好些事件又找到

D:\tempfile\openfire\Openfire-4.4.0\xmppserver\src\main\java\org\jivesoftware\util\LocaleUtils.java

这个类,跟上面的方法一样,也是在

String getLocalizedString(String key, Locale locale, List arguments,
        ResourceBundle bundle)

这个方法中,更改字符串编码:

public static String getLocalizedString(String key, Locale locale, List arguments,
        ResourceBundle bundle)
{
    if (key == null) {
        throw new NullPointerException("Key cannot be null");
    }
    if (locale == null) {
        locale = JiveGlobals.getLocale();
    }

    String value = getDefaultLocalizedString(key);

    // See if the bundle has a value
    try {
        // The jdk caches resource bundles on it's own, so we won't bother.
        //value = bundle.getString(key);
        //这里更改字符串编码
        try{
            String  value1 = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
            value = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
        }catch (Exception e){

        }finally {
            try{
                value = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
            }catch (Exception e){

            }
        }
        //修改结束
        // perform argument substitutions
        if (arguments != null) {
            MessageFormat messageFormat = new MessageFormat("");
            messageFormat.setLocale(bundle.getLocale());
            messageFormat.applyPattern(value);
            try {
                // This isn't fool-proof, but it's better than nothing
                // The idea is to try and convert strings into the
                // types of objects that the formatters expects
                // i.e. Numbers and Dates
                Format[] formats = messageFormat.getFormats();
                for (int i = 0; i < formats.length; i++) {
                    Format format = formats[i];
                    if (format != null) {
                        if (format instanceof DateFormat) {
                            if (arguments.size() > i) {
                                Object val = arguments.get(i);
                                if (val instanceof String) {
                                    DateFormat dateFmt = (DateFormat)format;
                                    try {
                                        val = dateFmt.parse((String)val);
                                        arguments.set(i, val);
                                    }
                                    catch (ParseException e) {
                                        Log.error(e.getMessage(), e);
                                    }
                                }
                            }
                        }
                        else if (format instanceof NumberFormat) {
                            if (arguments.size() > i) {
                                Object val = arguments.get(i);
                                if (val instanceof String) {
                                    NumberFormat nbrFmt = (NumberFormat)format;
                                    try {
                                        val = nbrFmt.parse((String)val);
                                        arguments.set(i, val);
                                    }
                                    catch (ParseException e) {
                                        Log.error(e.getMessage(), e);
                                    }
                                }
                            }
                        }
                    }
                }
                value = messageFormat.format(arguments.toArray());
            }
            catch (IllegalArgumentException e) {
                Log.error("Unable to format resource string for key: "
                        + key + ", argument type not supported");
            }
        }
    }
    catch (java.util.MissingResourceException mre) {
        Log.warn("Missing resource for key: " + key
                + " in locale " + locale.toString());
    }

    return value;
}

改完之后重新编译一下,不好使的话,将class文件覆盖到xmppserver-4.4.0.jar 这个jar包中对应的路径:

259.png


重启服务器,可以看到已经解决了乱码问题:

441.png







未定义标签
推荐阅读

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。


习惯沉淀
时间:2019-12-09 13:44:08

博主域名和logo不一致呀

tjk
2楼  tjk @Ta
时间:2021-05-11 10:42:43

无需这么麻烦 配置openfire.xml中locale即可 默认是en的

  登录