wechat4j获取用户昵称乱码修复

简介: wechat4j获取用户昵称乱码修复

项目对接微信公众号平台时,微信的官方给出的建议是使用wechat4j。官方建议的,自然心里踏实,但实际用起来时发现wechat4j埋有很多雷,最让人心烦意乱的就是中文乱码问题。


之前写过一篇为JAXB和response设置编码,解决wechat4j中文乱码,解决的是智能输入时反馈信息的乱码,遇到同样问题的伙伴可以去参考一下解决方案。


今天要写的是利用wechat4j获取用户昵称乱码的问题。


一、问题描述


UserManager userManager = new UserManager();

org.sword.wechat4j.user.User user = userManager.getUserInfo(tokenResponse.getOpenid());

thirdLoginMember.setThird_name(user.getNickName());


项目运行时,一旦昵称为中文,此方法获得的昵称就是乱码,引发乱码的原因其实很直白,无非就是编码方式不匹配。


二、问题分析


我们来追本溯源,看看以下的代码,我们能感受到问题具体出在哪。


wechat4j中的代码

public User getUserInfo(String openId) {
    return getUserInfo(openId, null);
}
public User getUserInfo(String openId, LanguageType lang) {
    String url = USER_INFO_GET_URL + TokenProxy.accessToken() + "&openid=" + openId;
    if (lang != null) {
        url += "&lang=" + lang.name();
    }
    String resultStr = HttpUtils.get(url);
    logger.info("return data " + resultStr);
    try {
        WeChatUtil.isSuccess(resultStr);
    } catch (WeChatException e) {
        logger.error(e.getMessage());
        e.printStackTrace();
        return null;
    }
    User user = JSONObject.parseObject(resultStr, User.class);
    return user;
}
public static String get(String url){
    return httpGet(url);
}
private static String httpGet(String url) {
    try {
        HttpEntity entity = Request.Get(url).
                execute().returnResponse().getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
    } catch (Exception e) {
        logger.error("get请求异常," + e.getMessage() + "\n get url:" + url);
        e.printStackTrace();
    }
    return null;
}


httpcore-4.3.3.jar中的代码

public static String toString(final HttpEntity entity)
    throws IOException, ParseException {
    return toString(entity, (Charset)null);
}
public static String toString(
        final HttpEntity entity, final Charset defaultCharset) throws IOException, ParseException {
    Args.notNull(entity, "Entity");
    final InputStream instream = entity.getContent();
    if (instream == null) {
        return null;
    }
    try {
        Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
                "HTTP entity too large to be buffered in memory");
        int i = (int)entity.getContentLength();
        if (i < 0) {
            i = 4096;
        }
        Charset charset = null;
        try {
            final ContentType contentType = ContentType.get(entity);
            if (contentType != null) {
                charset = contentType.getCharset();
            }
        } catch (final UnsupportedCharsetException ex) {
            if (defaultCharset == null) {
                throw new UnsupportedEncodingException(ex.getMessage());
            }
        }
        if (charset == null) {
            charset = HTTP.UTF8_CONTENT_CHARSET;
        }
        logger.info("输出流的转码方式为:" + charset);
        final Reader reader = new InputStreamReader(instream, charset);
        final CharArrayBuffer buffer = new CharArrayBuffer(i);
        final char[] tmp = new char[1024];
        int l;
        while((l = reader.read(tmp)) != -1) {
            buffer.append(tmp, 0, l);
        }
        return buffer.toString();
    } finally {
        instream.close();
    }
}


从上述代码中可得知,wechat4j在取得到参数后,调用httpcore-4.3.3.jar中的EntityUtils类的toString()方法,该方法默认使用的编码方式是“ISO-8859-1”。看到这里,你也许就恍然大悟了,原来如此嘛。那,该如何改动呢?


三、问题解决之道


wechat4j是一个jar包,git上提供了源码下载,你可以选择直接在项目中引入wechat4j.jar,也可以选择把源码作为一个导入项目引入到项目中,我选择的是第二种做法,这种方案方便我们调试,以及修改源码。


在说解决之道之前,我先啰嗦一点关于eclipse中项目之间引用的注意事项。

image.png



上图是我项目中wechat4j源码的目录:


apache.http就是httpcore-4.3.3.jar的源码。

sword是wechat4j.jar的源码。

tomcat 7 是把该项目引入到一个web项目后,自动出现的,我顺带把wechat4j所需要的jar包添加到lib包下。

本来wechat4j是一个Java项目。

image.png


关于deployment assembly我并没有很好的理解其作用(Define packaging structure for this Java EE Web Application project.),大致的意思是把被引入的项目编译成jar包供引用项目使用。

image.png



build path中引入项目。

image.png



project reference。


关于这三个之间的关联关系,我真是没有搞明白,敬请小伙伴们指导。


PS:请特别注入,针对wechat4j的引入,被引入项目(ymeng)中不能再放httpcore-4.3.3.jar,否则wechat4j中的httpcore将不会起作用。


那么接下来,我们该好好看看怎么解决了,其实方法依然可知。


第一种,EntityUtils.toString()方法中设置编码方式。


return entity != null ? EntityUtils.toString(entity,"utf-8") : null;


这个其实应该交由wechat4j来做的, 但它坑了。


第二种,EntityUtils.toString方法中设置默认的编码方式为utf-8.


if (charset == null) {

  charset = HTTP.UTF8_CONTENT_CHARSET;

}


看完本篇文章,大家是否略有所获?


相关文章
|
2月前
|
SQL 关系型数据库 数据库
微信为什么使用 SQLite 保存聊天记录?
微信为什么使用 SQLite 保存聊天记录?
|
缓存 小程序 JavaScript
附解决方案,小程序用户昵称突然变成了“微信用户”,而且头像也显示不了?
附解决方案,小程序用户昵称突然变成了“微信用户”,而且头像也显示不了?
546 0
|
小程序 JavaScript
零基础学小程序006---小程序获取用户信息用户昵称
零基础学小程序006---小程序获取用户信息用户昵称
|
SQL 存储 关系型数据库
微信为什么使用 SQLite 保存聊天记录?(来长长见识了!)
微信为什么使用 SQLite 保存聊天记录?(来长长见识了!)
351 0
微信为什么使用 SQLite 保存聊天记录?(来长长见识了!)
|
数据安全/隐私保护
成功解决pdf文档加密后时间久了忘记密码—本文档有打开口令或修改口令—在线完美解决
成功解决pdf文档加密后时间久了忘记密码—本文档有打开口令或修改口令—在线完美解决
成功解决pdf文档加密后时间久了忘记密码—本文档有打开口令或修改口令—在线完美解决
苹果手机复制电话号码提示格式不正确
本文介绍解决苹果手机复制电话号码提示格式不正确的方法。
1581 0
|
SQL 安全 数据安全/隐私保护
网站title标题被改并被百度网址安全中心提醒的解决办法
国庆假日期间我们Sine安全接到众多网站站长求助网站标题被改导致在百度搜索中百度安全中心提醒被拦截,导致网站正常用户无法浏览网站被跳转到一些菠菜du博网站,而且很明显的一个特征就是在百度中搜索关键词的网站快照标题被修改成了一些与网站本身内容不相关的页面,而且发现网站首页文件如index.php或index.html被增加了一些可疑的加密代码。
265 0
网站title标题被改并被百度网址安全中心提醒的解决办法
|
移动开发 PHP
php发邮件foxmail标题显示乱码问题解决方案
之前在大神那里找了一个SMTP发送邮件的源码,应用之后是可以发送邮件了,然后web查看邮件也正常,但是foxmail客户端一直显示标题乱码,正文是正常的,几经搜索之后,终于发现原来邮件是base64编码的,所有需要将标题经过编码之后才发送,测试之后,果然正常了。
2247 0