wechat4j获取用户昵称乱码修复

简介: 版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/53556008 项目对接微信公众号平台时,微信的官方给出的建议是使用wechat4j。
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/53556008

项目对接微信公众号平台时,微信的官方给出的建议是使用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中项目之间引用的注意事项。

这里写图片描述

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

  1. apache.http就是httpcore-4.3.3.jar的源码。
  2. sword是wechat4j.jar的源码。
  3. tomcat 7 是把该项目引入到一个web项目后,自动出现的,我顺带把wechat4j所需要的jar包添加到lib包下。
  4. 本来wechat4j是一个Java项目。

这里写图片描述

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

这里写图片描述

build path中引入项目。

这里写图片描述

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;
}

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

相关文章
|
小程序 JavaScript 前端开发
微信小程序上传头像和昵称持久化保存
微信小程序上传头像和昵称持久化保存
1132 0
|
缓存 小程序 JavaScript
附解决方案,小程序用户昵称突然变成了“微信用户”,而且头像也显示不了?
附解决方案,小程序用户昵称突然变成了“微信用户”,而且头像也显示不了?
602 0
|
小程序 JavaScript
零基础学小程序006---小程序获取用户信息用户昵称
零基础学小程序006---小程序获取用户信息用户昵称
|
SQL JavaScript 前端开发
正则表达式--QQ微信、优酷前端 邮箱正则表达式验证 Bug
但凡稍微有点资历的程序员,都免不了要写正则表达验证算法。最近见到好几个正则表达式的Bug,抽空写出来 拿邮箱验证来说,网上绝大部分人写的邮箱验证正则表达式代码都不能验证这邮箱
|
Java 应用服务中间件 开发工具
wechat4j获取用户昵称乱码修复
wechat4j获取用户昵称乱码修复
186 0
wechat4j获取用户昵称乱码修复
|
数据安全/隐私保护 Windows
Windows 技术篇-Foxmail邮箱客户端使用过程中一直提示“密码错误,请输入您的QQ密码”问题解决方法
Windows 技术篇-Foxmail邮箱客户端使用过程中一直提示“密码错误,请输入您的QQ密码”问题解决方法
1965 0
Windows 技术篇-Foxmail邮箱客户端使用过程中一直提示“密码错误,请输入您的QQ密码”问题解决方法
苹果手机复制电话号码提示格式不正确
本文介绍解决苹果手机复制电话号码提示格式不正确的方法。
1652 0