批量获取微信公众号用户openID及用户信息 - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 公众号相关 >

批量获取微信公众号用户openID及用户信息

发表时间:2020-10-19

发布人:葵宇科技

浏览次数:41

本文代码基于微信开发文档-用户管理-获取用户列表一节开发

在使用代码之前请确认你已阅读并理解上面文档提到的相关知识。

文章目录

      • 1、工具类的构建
      • 2、数据实体类的构建
      • 3、批量获取用户openid
      • 4、批量获取用户信息

1、工具类的构建

首先创建如下代码到RestTemplateUtil.java文件中,RestTemplateUtil这个类将帮助我们解析微信服务器发送过来的数据

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;

public class RestTemplateUtil {
    public static RestTemplate getInstance() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());
        return restTemplate;
    }
}

class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    public WxMappingJackson2HttpMessageConverter(){
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.TEXT_PLAIN);
        mediaTypes.add(MediaType.TEXT_HTML);
        setSupportedMediaTypes(mediaTypes);
    }
}

获取微信公众号access_token的函数,需要使用fastjson工具包,LOGGER为日志输出类,注意:如果不是测试公众号的话,请确保请求的IP地址在公众号IP白名单中,否则无法获取access_token,access_token一般7200秒后过期。

/**
 * @param appid 微信公众号appid
 * @param secret 微信公众号sectet
 * @return 微信公众号access_token
 */
public String getWxAccessToken(String appid, String secret){
    RestTemplate restTemplate = RestTemplateUtil.getInstance();
    try {
        JSONObject jsonObject = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/token?" +
                "grant_type=client_credential&appid=%s&secret=%s", appid, secret), JSONObject.class);
        if(jsonObject.get("access_token") == null){
            throw new Exception(jsonObject.get("errcode").toString() + ":" + jsonObject.get("errmsg"));
        }else {
            return jsonObject.get("access_token").toString();
        }
    }catch (Exception e){
        LOGGER.error(e.getMessage());
    }
    return "";
}

2、数据实体类的构建

需要准备三个实体类,一个保存openID列表,一个保存用户信息,一个保存用户信息列表,保存openID的实体类看起来如下所示:
在这里插入图片描述
相对应的,我们构造出如下实体类:

public class WxUsersListEntity {
    int total;
    int count;
    openidList data;
    String next_openid;

    public class openidList{
        List<String> openid;
		//get and set method
		...
    }
	
	//get and set method
	...
}

同理:
保存用户信息的实体类看起来像这样:
在这里插入图片描述

相对应的,我们构造出如下实体类:

public class WxUserMsgEntity {
    public int subscribe;
    public String openid;
    public String nickname;
    public String headimgurl;
    public String unionid;
    
    //get and set method
	...
}

你可以只挑你感兴趣的内容来保存,这里我只保存以上5条信息。这里提示一下,如果你需要将用户信息保存到数据库,格外注意nickname,他是utf8mb4编码。如果要将nickname保存到数据库,你有两种选择:

  • 将数据库修改到支持utf8mb4来保存,参考这里
  • 过滤掉nickname中的emoji表情来保存,参考这里

最后是保存用户信息列表的类,他看起来是这样:
在这里插入图片描述
所以构造的实体类是这样:

public class WxUserMsgList{
   public List<WxUserMsgEntity> user_info_list;

    //get and set method
	...
}

3、批量获取用户openid

准备好以上的内容后,就可以开始按照微信文档中的逻辑编写代码了。首先我们来获取用户的openid列表,该函数返回的是一个保存所有用户openid的List。

public List<String> getUsersOpenID(String access_token){
    RestTemplate restTemplate = RestTemplateUtil.getInstance();
    List<String> usersOpenID = new ArrayList<>();
    WxUsersListEntity wxUsersListEntity = new WxUsersListEntity();

    //获取所有微信用户的openID
    wxUsersListEntity = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/get?" +
            "access_token=%s",access_token), WxUsersListEntity.class);
    usersOpenID.addAll(wxUsersListEntity.getData().getOpenid());

    while(wxUsersListEntity.getCount() == 10000){
        wxUsersListEntity = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/get?" +
                "access_token=%s&next_openid=%s", access_token, wxUsersListEntity.getNext_openid()), WxUsersListEntity.class);

        if(wxUsersListEntity.getCount() == 0) {
            break;
        }else {
            usersOpenID.addAll(wxUsersListEntity.getData().getOpenid());
        }
    }
    return usersOpenID;
}

4、批量获取用户信息

之后根据用户openid的List去获取用户的信息,函数如下:

/**
 * 根据列表中的openID返回用户信息,最大不超过100(因为微信服务器最多一次只支持拉取100条)
 * @param openIDs
 * @return 微信用户信息列表
 */
public List<WxUserMsgEntity> getUsersMsg(List<String> openIDs, String access_token) throws Exception {
    if(openIDs.size() > 100) { throw new Exception("openIDs too long, must less or equals 100");}

    JSONObject request = new JSONObject();
    JSONArray openidList = new JSONArray();

    for(String s:openIDs){
        JSONObject openId = new JSONObject();
        openId.put("lang", "zh_CN");
        openId.put("openid", s);
        openidList.add(openId);
    }
    
    request.put("user_list", openidList);

    RestTemplate restTemplate = RestTemplateUtil.getInstance();

    WxUserMsgList list = restTemplate.postForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s", access_token),
    request, WxUserMsgList.class);

    return list.getUser_info_list();
}

在3,4步中使用getForObjectpostForObject函数的时候,我没有考虑获取出错的情况,但是我在获取access_token的函数中给出了处理出错情况的示例,即:先将数据接收到JSONObject中,判断是否有我们需要的字段,没有的话说明出现了错误。如果没有出错,你可以使用JSONObject的public <T> T toJavaObject(Class<T> clazz)函数将JSONObject转为数据实体类处理。

以上我们就完成了批量获取微信用户openID及用户信息的目标,如果使用过程中出现问题,可以在文章下评论,我会及时回复,让后来者不踩坑。

相关案例查看更多